This is due to wrap: true
in the r.js config. Here's a simple configuration that isolates the issue:
main.js
define([ 'legacy' ], function(legacy) {
var greeting = 'hi';
console.log(greeting, legacy.foo);
});
legacy.js
var globalThing = { foo: 1, bar: 2 };
build.json
{
"name": "main",
"optimize": "none",
"out": "main-built.js",
"shim": { "legacy": { "exports": "globalThing" } },
"wrap": true
}
Let's run r.js (r.js -o build.json
) and consider the result (formatted by me):
(function() { // this immediately-invoked function expression (IIFE)
// is here because r.js has "wrap: true" in the config
var globalThing = { foo: 1, bar: 2 };
// code generated from the "shim" entry in the config
define('legacy', function(global) {
return function() {
var ret, fn;
// since global.globalThing is undefined,
// that's where it goes wrong
return ret || global.globalThing;
};
}(this));
define('main', [ 'legacy' ], function(legacy) {
var greeting = 'hi';
console.log(greeting, legacy.foo);
});
})(); // end of the IIFE
As you can see from the code above, globalThing
isn't global any more. The same happens with the stack and highlight libraries in your project as they use var
and function declarations to define their globals.
To tackle this issue, we have a couple of options. The first is to consider whether you really need wrap: true
in the config. If you drop it, the globals will get global again and everything should start working as expected. The second option is to try adding wrapShim: true
to the config. You can read about nuances of using this option here. If we try it with our sample configuration, we'll get something like this:
(function() {
(function(root) {
define('legacy', [], function() {
return function() {
var globalThing = { foo: 1, bar: 2 };
return root.globalThing = globalThing;
}.apply(root, arguments);
});
})(this);
define('main', [ 'legacy' ], function(legacy) {
var greeting = 'hi';
console.log(greeting, legacy.foo);
});
})();
Looks good to me.