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?
-
1did you find the solution to this problem?stevensagaar– stevensagaar2017-03-27 23:04:07 +00:00Commented Mar 27, 2017 at 23:04
-
@stevensagaar unfortunately notFabian Schmengler– Fabian Schmengler2017-03-28 05:47:49 +00:00Commented Mar 28, 2017 at 5:47
-
2If I find one, I'll add an answer hereFabian Schmengler– Fabian Schmengler2018-10-22 07:01:01 +00:00Commented 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!Fabian Schmengler– Fabian Schmengler2018-12-10 10:05:25 +00:00Commented Dec 10, 2018 at 10:05
-
3Have you tried rewriting getConfig function in vendor/magento/framework/RequireJs/Config.php or you need to write plugins in requirejs requirejs.org/docs/plugins.htmlArshad M– Arshad M2018-12-13 13:32:40 +00:00Commented Dec 13, 2018 at 13:32
1 Answer
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– Alex2018-12-13 16:53:19 +00:00Commented Dec 13, 2018 at 16:53
-
1Or can $this->fileSource->getFiles be rewritten instead? Just to not copy to much code ...Alex– Alex2018-12-13 16:54:01 +00:00Commented Dec 13, 2018 at 16:54
-
3@Alex You could as well use a plugin and use an
aroundGetConfig()orafterGetConfig()method in order to achive the conditional loading then we don't have to overwrite itDaniel– Daniel2018-12-14 06:51:02 +00:00Commented Dec 14, 2018 at 6:51 -
Looks promising, thank you! I already upvoted, will try it out asap before accepting the answerFabian Schmengler– Fabian Schmengler2018-12-15 10:35:51 +00:00Commented 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_disablegemig_hol– gemig_hol2018-12-16 12:06:57 +00:00Commented Dec 16, 2018 at 12:06