I am upgrading a project from Dojo 1.6.1 using AMD and RequireJS to Dojo 1.7.1 with its new AMD loader. I have to deal with old JavaScript files, not written as AMD modules, and have to load them in the correct order.
Before I used the RequireJS order plugin, but it does not seem to work with Dojo AMD Loader. I can not find anything about it in the loader documentation or the Dojo Build System documentation.
Any thoughts about this? If there is no order plugin, how should I handle plain JavaScript files together with Dojo 1.7? Do I need to handle them separately, or are there functionality for this in the loader or build system?
I'm just learning about this myself, but the documentation I found refers to Generic Script Injection
Load your generic scripts as described in the docs, while specifying {async: 0} as a configuration option for require(). This, to my understanding, does load the scripts in the order that you specify in the the second parameter (the array containing the script filenames/paths)
My example:
require({async:0},['test1.js','test2.js','test3.js'],function(){
//do stuff with reference to loaded scripts
});
My local tests show if I change config to {async: 1} the scripts load in a different order to what I specified. So far I haven't tracked this down in the dojo loader code, but it seems to make sense, and work, and isn't a hack.
I'd like to propose another approach for such a dependency module as mentioned in the comments above. The problem is that define
doesn't accept an async
parameter. Using a simple require
inside the define
function introduces a race condition because the code of the required modules is not executed yet.
Example (WRONG):
oldCode.js
window.foo = function(){};
legacyWrapper.js
define(["require"],function(require){ require({async:0},["./oldCode"]); })
code.js
define(["./legacyWrapper"],function(){ window.foo(); //throws exception, foo has not been loaded yet. })
(jsFiddle demo)
However, there is a solution to this problem. You need to return a Deferred that gets resolved as soon as all modules are loaded. The following example loads a,b,c,d in order.
define(["require","dojo/Deferred"],function(require,Deferred){ var def = new Deferred(); require({async:0}, ["./moduleA", "./moduleB", "./moduleC", "./moduleD"], function(){ def.resolve(); }); return def; })
To access properties defined in moduleA, you can now use
require(["legacyDeps"],function(legacyDeps){ legacyDeps.then(function(){ //It's save to assume that all legacy modules have been loaded here. }); });
I don't think plugins are generally compatible across AMD loaders. It's not optimal, but you can probably use dojo/text! with an eval. That would inline the content at buildtime.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With