I'm following the guide for advanced bundling of JavaScript (https://devdocs.magento.com/guides/v2.3/performance-best-practices/advanced-js-bundling.html) but when I'm running the "r.js -o" command to perform the actual bundling (https://devdocs.magento.com/guides/v2.3/performance-best-practices/advanced-js-bundling.html#part-2-...) I get the following error:
ReferenceError: XMLHttpRequest is not defined In module tree: mage/dataPost Magento_Ui/js/modal/confirm Magento_Ui/js/modal/modal text at createRequest (eval at <anonymous> (/path/to/webshop/node_modules/requirejs/bin/r.js:27737:33), <anonymous>:70:19) at /path/to/webshop/node_modules/requirejs/bin/r.js:28332:19 at /path/to/webshop/node_modules/requirejs/bin/r.js:3059:39 at /path/to/webshop/node_modules/requirejs/bin/r.js:2999:25 at Function.prim.nextTick (/path/to/webshop/node_modules/requirejs/bin/r.js:28083:9) at Object.errback (/path/to/webshop/node_modules/requirejs/bin/r.js:2998:26) ...
Has anyone run into this error, is there any knowledge/experience to share about this?
Solved! Go to Solution.
Ok, I've finally got this working after sustaining majors headaches.
The original problem with the XMLHttpRequest was fixed by using the RequireJS default text-loader "requirejs/test", instead of the magento one.
I've dropped the idea of bundling anything from the Magento_Ui module because it wouldn't work (is gets mapped or loaded differently because of some Magento magic). This also accounts for most of the files from the "/lib/web/..." directory.
Next I've added a new "requirejs-config-optimized.js" file that I load after the regular "requirejs-config.js" file in which I write the bundle eventual RequireJS configuration for the bundles.
Then I added some magic to remove/exclude components that have a mixin defined on it from the bundle definition, because bundling a component that has a mixin defined on it doesn't work.
It was quite a hell of a work, but now I've got a gulp-task to optimize the assets after "setup:static-content:deploy" and before we wrap the codebase and deploy it on production. It is however sad that I cannot (yet) bundle assets from "/lib/web/..." and Magento_Ui because that still accounts for a big payload.
Hello @klaas_werkt
Your error seems duplicate of below shared error:
https://stackoverflow.com/questions/32604460/xmlhttprequest-module-not-defined-found
Please try this if this help, Thanks
@Manish MittalI know Google, and I know that the XMLHttpRequest is an object within the web browser.
This problem is not a duplicate, but specifc to the usage of r.js wirth the config that is provided by the Magento guide. The problem is I get this error when running a command-line tool, so this tool should not perform a XHR. I can't figure out why this would happen as this r.js optimizer is designed to be executed from the command line (or on a node server if you will).
I found that require.js uses XHR to load text files. These are html template files, which can also be dependencies for modules, such as:
'text!ui/template/collection.html'
If any of these dependencies needs to loaded require.js - and apparently also r.js (the optimizer) - uses an XHR to load the asset. Which of course breaks on th e command-line.
So I wonder how the guide on https://devdocs.magento.com/guides/v2.3/performance-best-practices/advanced-js-bundling.html could ever work. Anyone who managed to get this working?
Ok, so I'm a little futher and found the culprit:
The Magento "build.js" configuration (and the automatically generated "requirejs-config.js" aswell) contain the following line to load a text module:
'text': 'mage/requirejs/text',
This module is used to load the previously mentioned text files (html files) such as:
'text!Magento_Tax/template/checkout/minicart/subtotal/totals.html'
.. and replace the require-js default text loader:
'text': 'requirejs/text',
This magento version of the text loader uses XHR to load the text assets. Also in the r.js optimization - which is ran on the command-line, that doesn't support XHR ofcourse.
Logically, I could switch to using the default require-js text loader (as in the example of @antonkril: https://github.com/antonkril/magento-rjs-config) however, this break upon trying to load certain assets that are not present in the the directory after deploying static content. For example:
'text!ui/template/tooltip/tooltip.html'
There is no such directory "path/to/theme/en_US/ui". But this asset is required as such in both the "Advancend JavaScript bundling" guide as the example by Anton Kril. (The mentoined file can be found in "path/to/theme/en_US/Magento_UI/templates/tooltip/tooltip.html").
Anyone any idea how to get this working on Magento 2.2.6?
Ok, so now a little further yet and overcome the problems above by rewriting:
'text': 'mage/requirejs/text',
to:
'text': 'requirejs/text',
This resolves correctly now and I can generate optimized bundles.
In the guide however a method is used to append the bundle definitions to the requirejs-config.js (https://devdocs.magento.com/guides/v2.3/performance-best-practices/advanced-js-bundling.html#part-2-..., step 4). This works on my machine aswell, so far so good. But when I view any page on the frontend, this file (requirejs-config.js) is regenerated. Without the bundle definitions.
I know the guide is written for Magento 2.3, so maybe this functionality is changed in there, but how can this be overcome on Magento 2.2.6? Should I impeed the re-generation of the requirejs-config.js file? Can I do so without repercussion?
Ok, I've finally got this working after sustaining majors headaches.
The original problem with the XMLHttpRequest was fixed by using the RequireJS default text-loader "requirejs/test", instead of the magento one.
I've dropped the idea of bundling anything from the Magento_Ui module because it wouldn't work (is gets mapped or loaded differently because of some Magento magic). This also accounts for most of the files from the "/lib/web/..." directory.
Next I've added a new "requirejs-config-optimized.js" file that I load after the regular "requirejs-config.js" file in which I write the bundle eventual RequireJS configuration for the bundles.
Then I added some magic to remove/exclude components that have a mixin defined on it from the bundle definition, because bundling a component that has a mixin defined on it doesn't work.
It was quite a hell of a work, but now I've got a gulp-task to optimize the assets after "setup:static-content:deploy" and before we wrap the codebase and deploy it on production. It is however sad that I cannot (yet) bundle assets from "/lib/web/..." and Magento_Ui because that still accounts for a big payload.
I had similar issues. Thank you for your detailed posts. It helped.
Thanks for sharing this.
I run to the error in part 2 step 4 of the guide. After adding the code that configures requirejs to use bundles which is:
onModuleBundleComplete: function (data) { function onBundleComplete (config, data) { const fileName = `${config.dir}/requirejs-config.js`; const bundleConfig = {}; bundleConfig[data.name] = data.included; bundleConfig[data.name] = bundleConfig[data.name].map(bundle => bundle.replace(/\.js$/, '')); const contents = `require.config({ bundles: ${JSON.stringify(bundleConfig)}, });`; fs.appendFile(fileName, contents); } onBundleComplete(config, data); }
i get following error after running r.js -o command:
Error: TypeError [ERR_INVALID_CALLBACK]: Callback must be a function at maybeCallback (fs.js:128:9)
Please, help!
Found this:
onModuleBundleComplete: function (data) { function onBundleComplete (config, data) { const fileName = `${config.dir}/requirejs-config.js`; const bundleConfig = {}; bundleConfig[data.name] = data.included; bundleConfig[data.name] = bundleConfig[data.name].map(bundle => bundle.replace(/\.js$/, '')); const contents = `require.config({ bundles: ${JSON.stringify(bundleConfig)}, });`; fs.appendFile(fileName, contents, function (err) { if (err) throw err; console.log('Saved!'); }); } onBundleComplete(config, data); }