Search code examples
requirejsgruntjsgrunt-contrib-requirejs

Combining files using requirejs and grunt


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.


Solution

  • 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
      });