javascriptcoffeescriptrequirejsgruntjsgrunt-contrib-requirejs

RequireJS Optimizer from mainConfigFile not working


I am using grunt-requirejs and my app structure looks like this:

site/
  dev/
    index.html
    config.coffee
    app.coffee
    etc.
  srv_dev/
    index.html
    config.js
    app.js
    etc.
  dist/
  node_modules/
  Gruntfile.coffee

When I run grunt dev files get compiled to js from coffee among other tasks and copied from dev/ to srv_dev/ and then are served from there.

My grunt dist task does what dev does and then runs a requirejs task, which, I hope, should compile / combine all the main dependancies of my app, but still allow for require(somevar) and define calls to run later on. Basically I have some parts of my single-page app which dont load until the user clicks on the link to it, which fires off a requrire() and define() call.

My current problem seems quite basic... I have set up my requirejs grunt task as follows:

requirejs:
  options:
    baseUrl: './'
    mainConfigFile: 'srv_dev/config.js'
  dist:
    options:
      out: 'dist/script.js'

This throws Error: Error: Missing either a "name", "include" or "modules" option

I have read most of the optimizer docs as well as the example build file and don't understand what is going on with this error. tkellen in this project uses the name option for almond.js -- but I don't think I want to do that, because I need those lazy - loader require() calls. The example build file states: "Just specifying a module name means that module will be converted into a built file that contains all of its dependencies." So that was my next attempt:

requirejs:
  options:
    baseUrl: './'
    name: 'srv_dev/config.js'
  dist:
    options:
      out: 'dist/script.js'

With this I get Error: ENOENT, no such file or directory >> '/Users/user/Desktop/project/site/app.js'

So it finds config.js, but then can't find the paths listed in the config, because it using the baseUrl of the require.js config.

And if I specify the baseUrl of './srv_dev' in the requirejs task config then it cant find my config.js file. I have tried a variety of paths to get this to work with no luck. I think the gruntfile needs to be in the same dir as the config.js file, but thats not how my project is set up.

Thanks Folks !!!

Here is the full text of my config.coffee file

config =

  baseUrl: './'

  paths:
    # require plugins
    text             : '/components/requirejs-plugins/lib/text'
    json             : '/components/requirejs-plugins/src/json'

    # lib
    jquery           : '/components/jquery/jquery'
    bootstrap        : '/components/bootstrap/dist/js/bootstrap'
    lodash           : '/components/lodash/dist/lodash'
    backbone         : '/components/backbone/backbone'
    marionette       : '/components/marionette/lib/backbone.marionette.min'
    handlebars       : '/components/handlebars/handlebars'
    prism            : '/components/customPrism/prism'
    coffeescript     : '/components/coffee-script/extras/coffee-script'

    # app
    app              : '/app/app'
    appSettings      : '/app/appSettings'
    AppController    : '/app/AppController'
    AppRouter        : '/app/AppRouter'

    postMasterRecord : '/posts/postMasterRecord'

    util             : '/scripts/util'
    templates        : '/templates'
    handlebarsHelpers: '/scripts/handlebarsHelpers'

  shim:
    # lib
    bootstrap:
      deps: ['jquery']
    backbone:
      deps: ['lodash', 'jquery']
      exports: 'Backbone'
    marionette:
      deps: ['backbone', 'lodash', 'jquery']
      exports : 'Marionette'
    handlebars:
      exports: 'Handlebars'
    templates:
      deps: ['handlebars']

    # app
    app:
      deps: [
        'marionette'
        'bootstrap'
        'handlebars'
        'templates'
      ]

  # deps: ['app']

require.config(config)

require(['app'])

Solution

  • It is perfectly acceptable to specify the same file as your mainConfigFile and for name so:

    requirejs:
      options:
        mainConfigFile: 'srv_dev/config.js'
        baseUrl: './srv_dev'
        name: 'config'
        findNestedDependencies: true
      dist:
        options:
          out: 'dist/script.js'
    

    mainConfigFile tells r.js "here is where you can find my runtime configuration", whereas name says "here is my main module". One does not imply the other.

    Without mainConfigFile r.js cannot find your runtime configuration. Without name (or include or modules), it cannot know what the entry point of your application is.

    findNestedDependencies: true is required for r.js to follow the require([app]) in your config.js file.