Magento2: RequireJS configurations are loaded alphabetically instead of in order of module dependencies

Created on 21 Apr 2016  路  9Comments  路  Source: magento/magento2

Steps to reproduce

  1. Install Magento from develop branch.
  2. Create a module named A_Test. The vendor name "A" is to place the module before Magento in the module load order.
  3. Create new JS file: A/Test/view/frontend/web/js/catalog-add-to-cart.js

    define([
       'jquery',
       'Magento_Catalog/js/catalog-add-to-cart'
    ], function ($) {
       "use strict";
    
       $.widget('Test.catalogAddToCart', $.mage.catalogAddToCart, {
           _create: function() {
               this._super();
               console.log('This is the A_Test catalog-add-to-cart.js file');
           }
       });
    
       return $.Test.catalogAddToCart;
    });
    
  4. Create a new RequireJS configuration file: A/Test/view/frontend/requirejs-config.js

    var config = {
       map: {
           '*': {
               catalogAddToCart: 'A_Test/js/catalog-add-to-cart'
           }
       }
    };
    
    
  5. Add the Magento_Catalog module as a dependency for the A_Test module in the A_Test modules module.xml file

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
       <module name="A_Test" setup_version="1.0.0">
           <sequence>
               <module name="Magento_Catalog"/>
           </sequence>
       </module>
    </config>
    
  6. Enable the module:

    bin/magento module:enable A_Test && bin/magento setup:upgrade && bin/magento cache:flush
    
  7. Delete the merged requirejs-config.js file to make sure a new one gets generated:

    rm -rf pub/static/_requirejs
    
  8. Open a browser
  9. Open the browsers console
  10. Load a product detail page

    Expected result

  11. You should see the console log "This is the A_Test catalog-add-to-cart.js file"

    Actual result

  12. The console log message is not displayed

    Why this is an issue

This devdocs guide shows how to extend/override an existing jQuery widget. This devdocs guide says

Dependencies between the modules or themes are considered as well.

So according to these two guides I should be seeing the expected result but I am not. If you review the merged requirejs-config.js file in the browser or in pub/static/_requirejs/frontend/Magento/blank/en_US/requirejs-config.js in the magento install's root directory, you will see that catalogAddToCart: 'Magento_Catalog/js/catalog-add-to-cart' is added to the file after catalogAddToCart: 'A_Test/js/catalog-add-to-cart'which results in the Magento_Catalog module's catalog-add-to-cart.js file will be mapped to catalogAddToCart instead of the A_Test module's catalog-add-to-cart.js

Ready for Work bug report

All 9 comments

Thanks for reporting. We will continue working with issue under internal ticket MAGETWO-52188. Please stay in touch.

This is not a bug @ntoombs19 you possibly picked the worst file possible to extend :) Currently if you see here

https://github.com/magento/magento2/blob/develop/app/code/Magento/Catalog/view/frontend/templates/product/view/addtocart.phtml

You will see at the bottom catalog-add-to-cart does NOT use the alias to load the require file therefore it will never pick up your changes. If you changed the string here 'Magento_Catalog/js/catalog-add-to-cart' to catalogAddToCart i.e the alias it will work as expected

@Zaylril That makes sense. It appears this occurs around Magento 2 with other scripts in several areas. Perhaps this issue should be renamed to to "Direct path RequireJS dependencies prevent overriding/extending those dependencies." I can't see the benefit in using the direct path in those dependencies. @guz-anton Is this something that could be updated in a future version of magento?

In the mean time, could something like this be used to reference the original script as a dependency while using the direct path as a mapping to the new script extending the original?

define([
    'jquery',
    'magento!Magento_Catalog::js/catalog-add-to-cart'
], function ($) {
    "use strict";

    $.widget('Test.catalogAddToCart', $.mage.catalogAddToCart, {
        _create: function() {
            this._super();
            console.log('This is the A_Test catalog-add-to-cart.js file');
        }
    });

    return $.Test.catalogAddToCart;
});
var config = {
    map: {
        '*': {
            'Magento_Catalog/js/catalog-add-to-cart': 'A_Test/js/catalog-add-to-cart'
        }
    }
};

See this paragraph in this devdoc for a reference as to what magento! does

The modular ID has magento! prefix and is used for loading the JavaScript modules. The ID Normalizer plugin converts the modular IDs into the file paths that are used by RequireJS to load the JavaScript modules.

I'm not sure if this is a legacy feature that never got updated in the devdocs because I don't see any instances of magento! being used in core code.

@ntoombs19 Yep you are correct. I've not tried the !magento syntax you linked. This instance is just the tip of the iceberg though, the Checkout JS does not use any aliases at all.

The only way to really extend a UiComponent for example in the checkout is to override the component definition to one in your Module and then extend this by injecting in the original file using the full path syntax. You cannot change anything or extend with require-js as no alias is ever used. It really needs to be improved as extending files is currently very difficult if not impossible in a lot of cases in Magento 2.

@Zaylril I tried my approach above using magento! and I ended up getting these two javascript errors in the console

http://m2.dev/static/frontend/Magento/blank/en_US/magento.js
Uncaught Error: Script error for: magento
http://requirejs.org/docs/errors.html#scripterror

It looks like it is in fact impossible to extend/override functionality in UiComponents that are referenced as dependencies by their direct path rather than a mapping alias without overriding the template or copying the entire original script into your own.

@guz-anton I would be happy to close this issue and open up a new one if that is the procedure for this sort of thing.

4141 This pull request will fix the issue for catalogAddToCart but there are other areas where a direct path is used as a dependency instead of a mapping alias.

Verified that the load order is not the issue here. It is the inconsistent use of aliases that makes overriding the magento javascript modules problematic.

Hi @ntoombs19 ,
Issue's fix has been delivered to mainline.
Fill free to review it. Please comment if any notice you have.

Its working fine on windows server but not working on linux server. What can be the issue

Was this page helpful?
0 / 5 - 0 ratings