13

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?

  • 1
    did you find the solution to this problem? – stevensagaar Mar 27 '17 at 23:04
  • @stevensagaar unfortunately not – Fabian Schmengler Mar 28 '17 at 5:47
  • 2
    If I find one, I'll add an answer here – Fabian Schmengler Oct 22 '18 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! – Fabian Schmengler Dec 10 '18 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 '18 at 13:32
3
+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;
    }
}
  • 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 '18 at 16:53
  • 1
    Or can $this->fileSource->getFiles be rewritten instead? Just to not copy to much code ... – Alex Dec 13 '18 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 '18 at 6:51
  • Looks promising, thank you! I already upvoted, will try it out asap before accepting the answer – Fabian Schmengler Dec 15 '18 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 '18 at 12:06

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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