I noticed that some of the legacy scripts that I'm working on for a project weren't working anymore after my team upgraded to Dojo 1.8. Specifically, the global variable that they created wasn't being created any more.
I dug around and found out that the Dojo 1.8 team is very much opposed to global variables. So opposed, in fact, that they make it physically impossible for the user to create a global variable in a required script using the following code at the end of their require:
req.eval =
function(text, hint){
return eval_(text + "\r\n////@ sourceURL=" + hint);
};
var eval_ = new Function('return eval(arguments[0]);');
That's wonderful and all, but the old code I'm working with can't be changed, so I've been trying to figure out how to get around this and execute the eval in the local context instead.
Fortunately, dojo.eval
is still there from older versions of Dojo, and that does what I want it to. So I just need to get access to req.eval
and change the function to do return dojo.eval(...)
or even just eval(...)
in certain instances.
The problem is, I haven't been able to figure out how to get access to req
. Here's what happens:
I include dojo.js
in script tags at the top of my HTML file. It loads in its own script file.
dojo.require
is accessible from my own files. It's defined with define
in the script file:
'dojo/_base/loader':function(){
define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
I'm not sure if that's important or not. Anyway, inside the scope of dojo.require
, I can see something called injectModule
, while in my own file I can't. injectModule
is a local variable so you can't see it with this
. It is defined in an anonymous function at the start of the file, i.e.
(function(){ ... injectModule = function(){} ... })();
Inside the injectModule
function, there's the following line:
req.getText(url, legacyMode!=sync, xhrCallback);
which goes to req.eval
. So injectModule
can see req
.
I'm not sure what to do. None of my nefarious JavaScript tricks have helped me even begin to navigate this gridlock of scopes. A good start would be figuring out how to see injectModule
from my outer script file that calls dojo.require
. I wasn't able to do it with 'bind', though, because it's a local variable defined in an anonymous function. Is this even going to be possible?
To make things a little easier, here's a summary:
File 1:
<script src="dojo.js"></script>
dojo.require(File 3);
console.log(globalVar);
File 2:
(function(){req.eval = unhelpful function})();
define(["require"], function(module){
dojo.require = function(x){req.eval(x)}
});
File 3:
globalVar = ...;
I can modify files 1 and 3, but file 3 will always need a global variable. I can't modify file 2. The goal is to change req.eval
in file 2 to be a better function.
Declaring the global variable earlier doesn't work because the scope change means file 3 still won't be able to see it.
Reflection and string replacement doesn't work because the scope is wrong and the JS is minified on the server-side.
Overwriting the methods from file 1 doesn't work because I can't see through the scope.
Using the JavaScript bind
function has been fruitless as well.
For this, dojo has created dojo.global
. It will point to the window
in which dojo has been loaded (nice for framed layouts).
So declare your global variables like so:
require([ "dojo/_base/kernel", ... ] , function(kernel) {
kernel.global.globalVariable = 1;
console.log('set')
})
dojo.addOnLoad(function() {console.log('get', globalVariable);});
Global scope can be accessed through the global window
object, so window.foo = 'bar'
is the same as creating a global variable foo
. More details about this here: https://stackoverflow.com/a/4862268/168382
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