Search code examples
javascriptgruntjsrequirejsgrunt-contrib-requirejs

Why does my grunt-contrib-requirejs does not optimize anything?


I am trying to get up and running with the grunt-contrib-requirejs task.
Being new to RequireJS in general and having never used the optimizer/r.js, I am really confused how to get this to work.

As a start, I have set up a simple directory structure like this:

root
├── js
│   ├── helper
│   │   ├── a.js
│   │   ├── b.js
│   │   └── d-dep.js
│   └── main.js
├── node_modules
│   └── [dependencies from package.json]
├── Gruntfile.js
└── package.json

I've tested it in the browser and all dependencies are loaded correctly there.

My Gruntfile:

module.exports = function(grunt) {
  grunt.config.init({
    requirejs: {
      options: {
        baseUrl: 'js/',
        mainConfigFile: 'js/main.js',
        dir: 'target/',
        keepBuildDir: true
      }
    }
  });

  require('load-grunt-tasks')(grunt);
}

main.js:

require(["helper/a", "helper/b"], function(util) {
  console.log('main.js loaded');
});

a.js

console.log('a.js loaded');

b.js

define(['js/helper/b-dep.js'], function(bdep) {
  console.log('b.js loaded');
});

b-dep.js

console.log('b.js dependency loaded');

When running grunt requirejs, I get a Done, without errors. message, but can't see any optimized file – I am guessing the error is in the Gruntfile, probably with the path.

Do you see anything that strikes you? Why is nothing optimized, although it says Done, without errors.?


Solution

  • You don't seem to be telling it to optimize something. You should have a name option set to tell it what the main module is. Also you are missing one level of configuration in the configuration you pass to grunt. The options object must be inside of a more specific target, like compile:

    requirejs: {
      compile: { // <<== nest the options in this.
        options: {
          baseUrl: 'js/',
          mainConfigFile: 'js/main.js',
          name : 'main', // <<=== add this
          dir: 'target/',
          keepBuildDir: true
        }
      }
    }
    

    Setting the mainConfigFile is not enough because this only tells the optimizer where it should get the runtime configuration from. It does not tell the optimizer that the file is a module. Note that the lack of .js extension in name is not an error. You should avoid using extension in module names, unless there is a specific reason that calls for an extension. And name is relative to baseUrl so this is why it is 'main' not 'js/main'.