title: Dojo 1.8 - create global variable in require
body: <p>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.</p>
  
  <p>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:</p>
  
  <pre><code>req.eval =
          function(text, hint){
              return eval_(text + "\r\n////@ sourceURL=" + hint);
          };
  var eval_ = new Function('return eval(arguments[0]);');
  </code></pre>
  
  <p>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.</p>
  
  <p>Fortunately, <code>dojo.eval</code> is still there from older versions of Dojo, and that does what I want it to.  So I just need to get access to <code>req.eval</code> and change the function to do <code>return dojo.eval(...)</code> or even just <code>eval(...)</code> in certain instances.</p>
  
  <p>The problem is, I haven't been able to figure out how to get access to <code>req</code>.  Here's what happens:</p>
  
  <p>I include <code>dojo.js</code> in script tags at the top of my HTML file.  It loads in its own script file.</p>
  
  <p><code>dojo.require</code> is accessible from my own files.  It's defined with <code>define</code> in the script file:</p>
  
  <pre><code>'dojo/_base/loader':function(){
  define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
  </code></pre>
  
  <p>I'm not sure if that's important or not.  Anyway, inside the scope of <code>dojo.require</code>, I can see something called <code>injectModule</code>, while in my own file I can't.  <code>injectModule</code> is a local variable so you can't see it with <code>this</code>.  It is defined in an anonymous function at the start of the file, i.e. </p>
  
  <pre><code>(function(){ ... injectModule = function(){} ... })();
  </code></pre>
  
  <p>Inside the <code>injectModule</code> function, there's the following line:</p>
  
  <p><code>req.getText(url, legacyMode!=sync, xhrCallback);</code></p>
  
  <p>which goes to <code>req.eval</code>.  So <code>injectModule</code> can see <code>req</code>.</p>
  
  <p>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 <code>injectModule</code> from my outer script file that calls <code>dojo.require</code>.  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?</p>
  
  <p>To make things a little easier, here's a summary:</p>
  
  <p>File 1:</p>
  
  <pre><code>&lt;script src="dojo.js"&gt;&lt;/script&gt;
  dojo.require(File 3);
  console.log(globalVar);
  </code></pre>
  
  <p>File 2:</p>
  
  <pre><code>(function(){req.eval = unhelpful function})();
  define(["require"], function(module){
      dojo.require = function(x){req.eval(x)}
  });
  </code></pre>
  
  <p>File 3:</p>
  
  <pre><code>globalVar = ...;
  </code></pre>
  
  <p>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 <code>req.eval</code> in file 2 to be a better function.</p>
  
  <p>Declaring the global variable earlier doesn't work because the scope change means file 3 still won't be able to see it.</p>
  
  <p>Reflection and string replacement doesn't work because the scope is wrong and the JS is minified on the server-side.</p>
  
  <p>Overwriting the methods from file 1 doesn't work because I can't see through the scope.</p>
  
  <p>Using the JavaScript <code>bind</code> function has been fruitless as well.</p>