最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dojo 1.8 - create global variable in require - Stack Overflow

programmeradmin0浏览0评论

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.

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.

Share Improve this question edited Oct 30, 2012 at 17:37 Andrew Latham asked Oct 30, 2012 at 17:00 Andrew LathamAndrew Latham 6,15214 gold badges51 silver badges88 bronze badges 2
  • Have you tried window.globalVar = 42 in file 3? – James Commented Oct 31, 2012 at 7:59
  • I had not and that worked, thank you. I don't really understand how n = 5 and window.n = 5 ended up being different. – Andrew Latham Commented Nov 1, 2012 at 18:24
Add a ment  | 

2 Answers 2

Reset to default 3

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./a/4862268/168382

发布评论

评论列表(0)

  1. 暂无评论