10

if you have a RequireJS module like so:

define(
    [
        '#patches',
        'backbone',
        'underscore',
        'react',
        '#allCollections',
        '#allModels',
        'app/js/routers/router',
        '#allTemplates',
        '#allControllers',
        '#allRelViews'
    ],

function(){

   var patches = arguments[0];

});

is there any way to know which dependency gets loaded first? In my case, '#patches' is a few window.X utility functions that I want to load before anything else. Do I need to configure this a different way to ensure this?

(in my case "#' is just my own notation to denote a module whose path is predefined in my main config file)

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • 1
    Like François Richard already said it is possible to influence the order in which the dependencies load implicitly but I would not recommend this as best practice. The usual way to go is that every dependency itself states it's dependencies, so if for example your `#allRelViews` needs the window utilities it should state this in it's `define` call. If you're not in control of the dependency I would suggest you use the *shim* approach that has been suggested in the accepted answer - the only other way I see is to modify the source, but you would have to do this for every update of the library. – mfeineis Aug 07 '15 at 08:11
  • 1
    Backbone and Underscore are AMD-compliant. (They call `define`.) If your own modules also call `define`, then most of the modules you show in your question cannot be used with the answer you accepted because **`shim` has a defined behavior only for non-AMD modules**. If you use `shim` for a module that calls `define`, the results are undefined. (When I tried it, it was usually ignored but since there are no semantics to it, RequireJS is free to change what it does from one release to the next. It's like an uninitialized pointer in C: there's no guaranteed what value it gets.) – Louis Aug 09 '16 at 15:05
  • Any solution for actual AMD modules? – Patrick Jul 31 '17 at 06:59
  • @Patrick use shim in the your require.js config, like the accepted answer says; although apparently only works for non-AMD modules? that seems strange, but I guess so. – Alexander Mills Jul 31 '17 at 07:11
  • the other way, which is more brute force, would be to nest require calls, like so `require('x', function(x){ require('y', function(){ require('z', function(z){})})})` – Alexander Mills Jul 31 '17 at 07:12
  • It's not that straight forward if it's an AMD module, nesting requires is not that straight forward either when the files are then minified – Patrick Jul 31 '17 at 07:23

1 Answers1

17

From the documentation : http://requirejs.org/docs/api.html#mechanics

"RequireJS waits for all dependencies to load, figures out the right order in which to call the functions that define the modules, then calls the module definition functions once the dependencies for those functions have been called. Note that the dependencies for a given module definition function could be called in any order, due to their sub-dependency relationships and network load order."

I think this may help: http://www.sitepoint.com/understanding-requirejs-for-effective-javascript-module-loading/ (see "Managing the Order of Dependent Files")

RequireJS uses Asynchronous Module Loading (AMD) for loading files. Each dependent module will start loading through asynchronous requests in the given order. Even though the file order is considered, we cannot guarantee that the first file is loaded before the second file due to the asynchronous nature. So, RequireJS allows us to use the shim config to define the sequence of files which need to be loaded in correct order. Let’s see how we can create configuration options in RequireJS.

requirejs.config({
  shim: {
    'source1': ['dependency1','dependency2'],
    'source2': ['source1']
  }
});

Hope it helps

EDIT: As said in comments, using Shim for AMD module is a bad idea, use only shim for non AMD modules and manage dependencies order there. For AMD module requirejs will manage the order of loading. A good link from the comments (thanks Daniel Tulp) ==> Requirejs why and when to use shim config

François Richard
  • 6,817
  • 10
  • 43
  • 78
  • so you can guarantee some load order by using the shim option – Alexander Mills Mar 17 '16 at 18:43
  • If the order is of consequence I think it should be grouped in more modules instead of shims. Requiring ordering will require the defined module to know things about each required module and it will be harder to reuse. – Asken Aug 07 '16 at 19:46
  • 3
    **`shim` is only for non-AMD modules.** Putting a `shim` configuration for an AMD module leads to undefined behavior. The OP is using Backbone and Underscore, which are both AMD modules (and have been for some time) so you cannot use `shim` for them. – Louis Aug 09 '16 at 15:00
  • [require.js documentation](http://requirejs.org/docs/api.html#config-shim): Remember: only use shim config for non-AMD scripts, scripts that do not already call define(). The shim config will not work correctly if used on AMD scripts, in particular, the exports and init config will not be triggered, and the deps config will be confusing for those cases. – Legends Nov 26 '16 at 17:24
  • @AlexanderMills I'm not downvoting him, just the message, here is some more info on it: https://stackoverflow.com/questions/15471088/requirejs-why-and-when-to-use-shim-config#15486691 – Daniël Tulp Feb 16 '18 at 08:15