Skip to content

x-magento-init initialisation not bound to happen in the right order. #17125

Closed
@kshaa

Description

@kshaa

Preconditions

  1. Magento 2.1.12

Steps to reproduce

  1. Inject a script very early in the page, that requires section-config.js and trigger its method getAffectedSections("some page").

Example reproduction code
(Or just use this example module - https://github.com/kshaa/m2-section-config-oddity/)

vendor/magento/module-theme/view/base/templates/root.phtml
(Root.phtml is not the proper place for customization, this is just an example for the issue)

<?php
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

?>
<!doctype html>
<html <?php /* @escapeNotVerified */ echo $htmlAttributes ?>>
    <head <?php /* @escapeNotVerified */ echo $headAttributes ?>>
        <?php /* @escapeNotVerified */ echo $requireJs ?>
        <?php /* @escapeNotVerified */ echo $headContent ?>
        <?php /* @escapeNotVerified */ echo $headAdditional ?>
    </head>
    <body data-container="body" data-mage-init='{"loaderAjax": {}, "loader": { "icon": "<?php /* @escapeNotVerified */ echo $loaderIcon; ?>"}}' <?php /* @escapeNotVerified */ echo $bodyAttributes ?>>
        <script>
            require([
                "Vendor_Theme/js/test"
            ], function(test) {
                var affectedSections = test("some page");
            });
        </script>
        <?php /* @escapeNotVerified */ echo $layoutContent ?>
    </body>
</html>

app/code/Vendor/Theme/view/frontend/web/js/test.js

define([
    'jquery', // Because everything requires jQuery
    'Magento_Customer/js/section-config'
], function($, sectionConfig) {

    return function(page) {
        sectionConfig.getAffectedSections(page);
    }
});

Expected result

  1. RequireJS will load section-config.js
  2. section-config.js constructs and initiates itself as required
  3. My injected script receives all affected sections for the URL "some page"

Actual result

  1. RequireJS loads section-config.js, but the internal data section-config requires for functioning isn't loaded yet
  2. section-config.js throws an error: "Uncaught TypeError: Cannot read property '*' of undefined"

Extra information

How I expect this internal section-config data load works usually

I think the data for section-config usually gets initiated in the following way:
vendor/magento/module-customer/view/frontend/templates/js/section-config.phtml template embeds the section-config with an x-magento-init script and also provides the required internal data
lib/web/mage/apply/scripts.js triggers early on page-load and transforms that x-magento-init into a virtual component (JS variable to-be-processed)
lib/web/mage/apply/main.js loads that section-config virtual component and binds the data from the template by passing it to a function that corresponds to the section-config returned object key "Magento_Customer/js/section-config".

Questions and concerns

  1. That "usual" data loading approach only works if section-config gets first loaded by the x-magento-init mechanism, however it's not given that will always be the case.
  2. Is it documented somewhere that I'm not allowed to use a bare-bones 'require' function for receiving section-config and other base features?
  3. I didn't manage to reproduce the following idea, but - if I x-magento-init'ed that test.js and once again required section-config, then it should also fail right? Because main.js (the x-magento-init JS mechanism) wouldn't have loaded the internal section-config data, because it simply uses a bare-bones require without any safety-checks.

Am I missing something critical here? Does the x-magento-init mechanism have drawbacks/limitations that I haven't seen in the documentations?
I just want to understand how this works, maybe this is actually easy and I didn't notice something.

P.S. I found this issue, because somewhere early in my page is a bare-bones JS using require that calls section-config within it's long dependency tree and fails in the aforementioned way and I can't easily fix it by replacing that initial script with x-magento-init or by moving it lower in the page, because I don't know what initial script triggers this faulty dependency tree.
P.P.S. This also seems like a race-condition which depends on the time it takes to load JS libraries over the network. Sometimes there is an error, sometimes not, but that shouldn't happen.

Metadata

Metadata

Assignees

Labels

Area: FrontendComponent: ThemeFixed in 2.4.xThe issue has been fixed in 2.4-develop branchIssue: Clear DescriptionGate 2 Passed. Manual verification of the issue description passedIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentReproduced on 2.2.xThe issue has been reproduced on latest 2.2 releaseReproduced on 2.3.xThe issue has been reproduced on latest 2.3 release

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions