Karma and RequireJS: avoid duplication in src and test RequireJS config

javascript, karma-runner, requirejs

Solution

I also hate to duplicate information. I work around that problem by using in my test suite an HTML setup which calls `require.config` twice.

So HTML in my test suite first loads RequireJS, and then the general configuration, which is in a file named `requirejs-config.js`:

<script type="text/javascript" src="lib/requirejs/require.js"></script>
<script type="text/javascript" src="requirejs-config.js"></script>

The `requirejs-config.js` file is nothing special. Here's an abbreviated version:

require.config({
 baseUrl: 'lib/',
 paths: {
   browser_test: '../../../browser_test',
   jquery: 'external/jquery-1.10.2',
   bootstrap: 'external/bootstrap/js/bootstrap.min',
   // [...]
 },
 packages: [
     {
         name: "lodash",
         location: "external/lodash"
     }
 ],
 shim: {
   bootstrap: {
     deps: ["jquery"],
     exports: "jQuery.fn.popover",
   },
   // [...]
 },
 config: {
   // [...]
 },
 enforceDefine: true
});

Then there is a `<script>` element which calls `require.config` with the settings that apply to the testing environment:

<script>
  require.config({
      paths: {
          'mocha': '/node_modules/mocha',
          'chai': '/node_modules/chai/chai'
      },
      shim: {
          'mocha/mocha': {
              exports: "mocha",
              init: function () { this.mocha.setup('bdd'); return this.mocha; }
          }
      },
      config: {
        // [...]
      }
  });
</script>

(The `'mocha/mocha'` shim looks funny but it is correct.)

In this specific case, the second call to `require.config` only adds new values to `paths`, `shim` and `config` but it is also possible to override earlier values. I could for instance change the path to which `'jquery'` resolves or change Bootstrap's shim.

You can see that I'm using Mocha + Chai for my test suite but the solution above is really not specific to Mocha at all.

Problem

For example, this test-main.js and this main.js has duplicated paths and shims. For large projects, there may be lots of them. I can even use grunt-bower-requirejs plugin to add installed Bower components into main.js, but after that, I have to copy them to test-main.js, either by hand or by program. Is there any convenient way to avoid this duplication, for example, tell RequireJS to include another config file?

Original source