0

I am trying to combine files using the grunt plugin for requirejs:

https://www.npmjs.org/package/grunt-contrib-requirejs

Here is the configuration:

requirejs:
      compile:
        options:
          #appDir: './'
          baseUrl: "client"
          mainConfigFile: "client/test1.js"
          name: "test1"
          out: "build/test.js"
          onModuleBundleComplete: (data) ->
            outputFile = data.path
            fs.writeFileSync(outputFile, amdclean.clean(
              'filePath': outputFile
            ))
          wrap:
            start: ""
            end: ""

Here are the input and output javascript

Input: test1.js

var x = console;
require(['test2'], function() {
  return console.log('Hello');
});

test2.js

x.log('this is test2');

test.js

var test2, test1;
x.log("this is test2"), null, test2 = undefined;
var x;
x = console, function () {
    return console.log("Hello")
}(), test1 = undefined;

The program works fine when loaded in browser with requirejs. But after the build is done, it does not work. This is because the definition x=console is provided before the code in test2.js is loaded when the modules are loaded using requirejs.

However, after the build, the definition x=console appears after the code from test2.js is loaded - which creates an error - because test2.js makes a call to x which is a global variable between the two js files.

I need to ensure requirejs builds the project into a single .js file while ensuring that no amd code is present (require/define) and the code is executed in the EXACT same order as with requirejs loaded in the browser.

EternallyCurious
  • 2,345
  • 7
  • 47
  • 78

1 Answers1

1

I think you may need a better understanding of the Asynchronous Module Definition (AMD) API specification. In either case I've modified your code a little bit to better adhere to AMD's syntax and I've created a a third file to define x like this:

  1. test1.js

    // Require the 'test2' module (which is passing x; which is equal to console)
    require(['test2'], function(x){
      x.log('this is test1');
    });
    
  2. test2.js

    // Define the 'test2' module which depends on the 'x' module
    define(['x'], function(x){
      x.log('this is test2');
      return x; // Return x; which is equal to console
    });
    
  3. x.js

    // Define the 'x' module which has no dependencies
    define(function(){
      console.log('this is x');
      return console; // Return console
    });
    
idbehold
  • 16,833
  • 5
  • 47
  • 74
  • I certainly do need that! That's actually why I asked a question, on quora. http://www.quora.com/Are-there-tutorials-similar-to-those-on-Code-School-for-these-topics .I appreciate your help. – EternallyCurious May 30 '14 at 15:34
  • Although I've assigned console to `x`, in reality `x` contains an instance of an object, that I want to be accessible as a global variable to all my javascript files and modules. In the way that you'e defined it, a new instance of `x` would be created every time its called by some javascript as this: `define(['x'], function(x){`. I want a single instance across my app. – EternallyCurious May 31 '14 at 09:09
  • One more point! The real problem I'm looking to have solved is the actual grunt configuration - which should build the project such that the compiled file would work in the exact same way as the files loaded individually with requirejs. The solution you've given does not provide that. – EternallyCurious May 31 '14 at 11:58
  • @EternallyCurious regardless of what object you assign to `x` it would always reference the same instance regardless of where you required it. All non-primitive data types in javascript are passed by reference. In either case, if you want a global object why not just do `window.x = { … }`? – idbehold May 31 '14 at 14:30