16

I would like to replace a RequireJs component only on certain conditions (for example, based on configuration). Is there any way to programmatically prevent loading of my module's requirejs-config.js or a different way to achieve it?

8
  • 1
    did you find the solution to this problem? Mar 27, 2017 at 23:04
  • @stevensagaar unfortunately not Mar 28, 2017 at 5:47
  • 2
    If I find one, I'll add an answer here Oct 22, 2018 at 7:01
  • 3
    @Alex if there's a solution for 2.2 or 2.3 I'd be happy, too :D updated the tags. Also, thanks for the bounty! Dec 10, 2018 at 10:05
  • 2
    Have you tried rewriting getConfig function in vendor/magento/framework/RequireJs/Config.php or you need to write plugins in requirejs requirejs.org/docs/plugins.html
    – Arshad M
    Dec 13, 2018 at 13:32

1 Answer 1

6
+200

Based on @Arshad M comment, you can add a di.xml with:

    <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <preference for="Magento\Framework\RequireJs\Config" type="<Vendor>\<ModuleName>\RequireJs\Config"/>

</config>

And in < Vendor >\< ModuleName >\RequireJs\Config.php override the getConfig function adding your condition and the module name that you don't want the requirejs to be loaded (probably from ScopeConfigInterface) :

   <?php

namespace <Vendor>\<ModuleName>\RequireJs;

use Magento\Framework\Filesystem\File\ReadFactory;
use Magento\Framework\View\Asset\Minification;
use Magento\Framework\View\Asset\RepositoryMap;

class Config extends \Magento\Framework\RequireJs\Config
{
    /**
     * @var \Magento\Framework\RequireJs\Config\File\Collector\Aggregated
     */
    private $fileSource;
    /**
     * @var ReadFactory
     */
    private $readFactory;
    /**
     * @var \Magento\Framework\Code\Minifier\AdapterInterface
     */
    private $minifyAdapter;
    /**
     * @var Minification
     */
    private $minification;
    /**
     * @var \Magento\Framework\View\DesignInterface
     */
    private $design;

    public function __construct(\Magento\Framework\RequireJs\Config\File\Collector\Aggregated $fileSource, \Magento\Framework\View\DesignInterface $design, ReadFactory $readFactory, \Magento\Framework\View\Asset\Repository $assetRepo, \Magento\Framework\Code\Minifier\AdapterInterface $minifyAdapter, Minification $minification, RepositoryMap $repositoryMap)
    {
        parent::__construct($fileSource, $design, $readFactory, $assetRepo, $minifyAdapter, $minification, $repositoryMap);
        $this->fileSource = $fileSource;
        $this->readFactory = $readFactory;
        $this->minifyAdapter = $minifyAdapter;
        $this->minification = $minification;
        $this->design = $design;
    }

    public function getConfig()
    {
        $distributedConfig = '';
        $customConfigFiles = $this->fileSource->getFiles($this->design->getDesignTheme(), self::CONFIG_FILE_NAME);
        foreach ($customConfigFiles as $file) {
            //Your condition
            if(true){
                if($file->getModule() == "Vendor_ModuleName"){
                    continue;
                }
            }

            /** @var $fileReader \Magento\Framework\Filesystem\File\Read */
            $fileReader = $this->readFactory->create($file->getFileName(), \Magento\Framework\Filesystem\DriverPool::FILE);
            $config = $fileReader->readAll($file->getName());


            $distributedConfig .= str_replace(
                ['%config%', '%context%'],
                [$config, $file->getModule()],
                self::PARTIAL_CONFIG_TEMPLATE
            );
        }

        $fullConfig = str_replace(
            ['%function%', '%usages%'],
            [$distributedConfig],
            self::FULL_CONFIG_TEMPLATE
        );


        if ($this->minification->isEnabled('js')) {
            $fullConfig = $this->minifyAdapter->minify($fullConfig);
        }

        return $fullConfig;
    }
}

UPDATE

After comments from @Alex and @Daniel: You can make an after plugin for getFiles from Magento\Framework\RequireJs\Config\File\Collector\Aggregated , so the new di.xml with this approach would be:

 <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <type name="Magento\Framework\RequireJs\Config\File\Collector\Aggregated">
        <plugin name="requirejsConfigPlugin"
                type="<Vendor>\<ModuleName>\Plugin\RequireJs\AfterFiles"
                sortOrder="100"
        />
    </type>
</config>

And at \< Vendor>\< ModuleName>\Plugin\RequireJs\AfterFiles, you can set your condition and module that the requirejs will not be load:

<?php

namespace <Vendor>\<ModuleName>\Plugin\RequireJs;

class AfterFiles
{
    public function afterGetFiles(
        \Magento\Framework\RequireJs\Config\File\Collector\Aggregated $subject,
        $result
    ){
        //Your condition
        if(true) {
            foreach ($result as $key => &$file) {
                //Module to exclude
                if ($file->getModule() == "Vendor_OtherModuleName") {
                    unset($result[$key]);
                }
            }
        }
        return $result;
    }
}
6
  • Nice! I think we could improve that by $fullConfig = parent::getConfig() and then modify $fullConfig to copy&paste less code. What do you think? Maybe we should make a mini-FOSS-module on github for this?
    – Alex
    Dec 13, 2018 at 16:53
  • 1
    Or can $this->fileSource->getFiles be rewritten instead? Just to not copy to much code ...
    – Alex
    Dec 13, 2018 at 16:54
  • 3
    @Alex You could as well use a plugin and use an aroundGetConfig() or afterGetConfig() method in order to achive the conditional loading then we don't have to overwrite it
    – Daniel
    Dec 14, 2018 at 6:51
  • Looks promising, thank you! I already upvoted, will try it out asap before accepting the answer Dec 15, 2018 at 10:35
  • 2
    @Alex following your suggestion I made a small module in github, where you can select the modules to disable the requirejs via magento backend. Check it out and maybe contribute github.com/MNGemignani/magento2_requirejs_disable
    – gemig_hol
    Dec 16, 2018 at 12:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.