RequireJS does not run data-main script before loading required modules

后端 未结 3 1646
慢半拍i
慢半拍i 2021-01-07 02:07

My project includes the following files:

./index.html
./js/main.js
./js/vendor/require.js
./js/viewmodel/vm.js

The index.html

相关标签:
3条回答
  • 2021-01-07 02:27

    I had the same problem. The architecture of the site that i was working was components that was loading asynchronous at each part of the page. Each component has its own html, css, and js code. So, my solution is to keep a guard function for all the required dependency code, to protect them from running before the main javascript file:

    index.html

    <head>
    <script type="text/javascript">
        window.BeforeMainGuard = {
            beforeMainLoadedFunctions: [],
            hasMainLoaded: false,
            guard: function( func ) {
                console.assert( typeof func === 'function' );
                if( this.hasMainLoaded ) {
                    func();
                }else {
                    this.beforeMainLoadedFunctions.push( func );
                }
            },
            onMainLoaded: function() {
                for( var i = 0; i<this.beforeMainLoadedFunctions.length; ++i ) {
                    var beforeMainLoadedFunction = this.beforeMainLoadedFunctions[i];
                      beforeMainLoadedFunction();
                }
                this.beforeMainLoadedFunctions = null;
                this.hasMainLoaded = true;
            }
        };
    </script>
    <script data-main="js/main.js" src="js/vendor/require.js"></script>
    <script type="text/javascript">
        window.BeforeMainGuard.guard( function() {
            require(['viewmodel/vm', 'ko'], 
                function(viewmodel, ko) {
                    ko.applyBindings(viewmodel);
                }
            );
        });
    </script>
    </head>
    

    js/main.js

    require.config({
      // your config
    });
    
    require( [ 'AppLogic' ], function( AppLogic ){      
        AppLogic.Init();
        window.BeforeMainGuard.onMainLoaded();
    } );
    
    0 讨论(0)
  • 2021-01-07 02:32

    to use the data-main attribute for configuring your whole application, it is necessary that it is the single entry point for all your code.

    your 2nd script block breaks this requirement by providing a 2nd entry point. since these entry points will resolve independently of each other (and asynchronously), you cannot rely on one to affect the other.

    to resolve it, refactor your code in a way that provides a single entry point to your application and do your configuration via this entry point.

    0 讨论(0)
  • 2021-01-07 02:41

    That's because requirejs sets the async. Attribute on the script.

    The boolean async attribute on script elements allows the external JavaScript file to run when it's available, without delaying page load first.

    This means that both scripts are loaded and evaluated parallel, so none of the two scripts can access methods or functions from the other one. If you want to define requirejs variables in one script you mustn't load that script with require js.

    For me there are three possibilities how you can solve that problem:

    • Add the content of main.js to your page (as you mention)
    • Load the main.js file without requirejs as normal script
    • Define the require config before loading the scripts (link to requirejs docu )
    0 讨论(0)
提交回复
热议问题