RequireJS, jquery still undefined

2019-02-20 03:15发布

问题:

I know this has already been discussed, but after searching for a while I can't figure out why my small setup does not load jquery correctly with requireJS.

I'm running a small sample html page from 'file://' and try to load 2 modules with a call to require:

  • jquery
  • a custom module I wrote

If my custom module loads correctly (i can use it with its alias in the require call, jquery is always undefined)

I tried to setup paths in require.config, as well as shim (exporting '$' or 'jQuery') but it does not work.

The only way i can get jquery to correctly load, is removing all paths definition and naming the jquery file on my filesystem 'jquery.js'

Here is my config:

main.js:

require.config({
    baseUrl: 'scripts',
    paths: {
        jquery: 'jquery-2.1.3.min' //does not work
        //jquery: 'http://code.jquery.com/jquery-2.1.3.min.js' //does not work either
    }
});

console.log( "main.js is loaded" );  //this is correctly ouputed to the console

test.html:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <!--
       ... page content ...
    -->

    <!-- main.js is loaded from data-main -->
    <script data-main="scripts/main" src="scripts/require.js"></script>
    <script type='text/javascript'>
      require(
          ['jquery','custom'],
          function($, Custom){
            console.info('$:');
            console.info($); //outputs undefined

            console.info('Custom:');
            console.info(Custom); //outputs my custom object        

          });
    </script>  
  </body>
</html>

Once again, it works if I remove all paths definition for jquery, and simply name my jquery js file 'jquery.js' but this is sloppy.

Can somebody points me on the right way to go ?

回答1:

The problem is that you load your RequireJS configuration, which is in main, through data-main. The data-main attribute merely tells RequireJS to load the module listed there but the loading is still asynchronous, so main may load after RequireJS tries to load jQuery. When this happens, RequireJS fails to find jQuery and $ is undefined. (Incidentally, I'd suggest setting enforceDefine to true in your RequireJS configuration so that you get an error message telling you when a module has not loaded. That's a better clue than having an undefined symbol.)

One solution would be to move your configuration outside of main. So you remove it from main and add it to a script element in front of the one loading RequireJS:

<script>
// RequireJS will use the value of `require` as its configuration.
require = {
    baseUrl: 'scripts',
    paths: {
        jquery: 'jquery-2.1.3.min'
    },
    enforceDefine: true
};
</script>
<script src="scripts/require.js"></script>

Or you can nest require calls to force main to load before any other module:

require(['main'], function () {
    require(['jquery','custom'], ...
});