javascriptrequirejsgrunt-contrib-requirejs

RequireJS bundles fail in optimizer - "modules share the same URL"


tl;dr

RequireJS optimizer doesn't like me defining bundle definitions on a module, but also does not find the modules if I don't define the bundles.

long version

I am getting the following error when trying to use the requirejs optimizer:

Error: Module loading did not complete for: scripts/simulation.bundle, app_mini, testservice
   The following modules share the same URL. This could be a misconfiguration if that URL only has one anonymous module in it:
   .../web/dist/scripts/app.bundle.js: app_mini, testservice

I am actually using grunt-contrib-requirejs to optimize my js scripts for production. It was all working fine before adding the simulator.bundle

I have 3 bundles:

This is the modules option of the requirejs grunt tasks

[{
    name: 'scripts/vendor.bundle',
    exclude: [],
    override: {
      paths: {
        angular: 'bower/angular/angular',
        jquery: 'bower/jquery/dist/jquery',
        ngRoute: "bower/angular-route/angular-route"
      },
      shim: {
        angular: {
          exports: 'angular',
          deps: ['jquery'] // make jquery dependency - angular will replace jquery lite with full jquery
        },
        bundles: {
          'scripts/app.bundle': ['app_mini', 'testservice'],
        },
      }
    }
  },
  {
    name: 'scripts/simulation.bundle',
    exclude: [],
    override: {
      paths: {},
      shim: {},
      bundles: {
        'scripts/vendor.bundle': ['angular', 'jquery'],
        'scripts/app.bundle': ['app_mini', 'testservice']
      }
    }
  },
  {
    name: 'scripts/app.bundle',
    exclude: ['scripts/vendor.bundle'],
    override: {
      paths: {
        app_mini: 'scripts/app.mini',
        testservice: 'scripts/features/test.service'
      },
      shim: {},
      bundles: {
        'scripts/vendor.bundle': ['angular', 'jquery']

      }
    }
  }
]

The bundles in simulation.bundle seem to be the problem. However, if I remove them, the files cannot be found:

>> Error: ENOENT: no such file or directory, open
>> '...\web\dist\app_mini.js'
>> In module tree:
>>     scripts/simulation.bundle

The simulation.bundle is just a dummy module, loading angular and app_mini:

define(['app_mini', 'angular'], function(app_mini, angular) {
    // nothing here
}

So either way, the optimizer cannot process the dependencies. How do I have to configure it to make it work?


Solution

  • Alright, once again I am posting the answer to my own question, and I hope some other people will benefit from my mistakes ;)

    So what I found out is:

    Bundle config is only for requireJS and not for the optimizer!

    The bundles I defined in the config are leading to the error of modules sharing the same url.

    The right way to do it, is to define ALL the paths for ALL the modules, and to specifically exclude the modules by name that should not be included in a module.

    For example, app_mini should go into the app.bundle, but because it is required in the simulation.bundle it would get included there, because excluding app.bundle is not yet possible (it has not been optimized at this point), we need to exclude app_mini directly.

    So a working config would look like this: (not tested)

    paths: {
        angular: 'bower/angular/angular',
        jquery: 'bower/jquery/dist/jquery',
        ngRoute: "bower/angular-route/angular-route"
        app_mini: 'scripts/app.mini',
        testservice: 'scripts/features/test.service'
    },
    shim: {
        angular: {
            exports: 'angular',
            deps: ['jquery'] // make jquery dependency - angular will replace jquery lite with full jquery
        }
    },
    
    modules: [
        {
            name: 'scripts/vendor.bundle',
            exclude: [],
        },
        {
            name: 'scripts/simulation.bundle',
            exclude: [`app_mini`],
        },
        {
            name: 'scripts/app.bundle',
            exclude: ['scripts/vendor.bundle'],
        }
    }]