Dependency Management Got Awesome CommonJS and AMD Compliant dependency loader for modern web apps

Inject.addRule

0.4.x

OLD: This is an old version of documentation. You probably want the most recent version of this document, from the sidebar on the right.
Inject.addRule(/regexMatch/?, weight?, { /* options */ });
Inject.addRule('string'?, weight?, { /* options */ });
Inject.addRule(/regexMatch/?, { /* options */ });
Inject.addRule('string'?, { /* options */ });

Sometimes, you need to modify the module you are downloading. Inject.addRule enable you to map a module to a new location, modify the contents of the file on the fly, add dependencies, or assign module exports.

Modules are assigned a weighted order, with LIFO (last-in-first-out). Why? Because 9/10 times your rules you add later are to override previous work. As of this doc, the other 1/10 times could benefit from a better matching statement.

The simplest use of Inject.addRule is to change the location of a specific module

Inject.addRule('module/path', {
  path: 'http://example.com/absolute/or/relative.js'
});

Full details on the options are below.

Rule Matching: options.matches

Either the first paramter to addRule can be a string or regex, or this can be assigned to the ruleSet’s options.matches value. When the match condition is met, the rule is applied. Strings match a literal 1:1 while regexes match based on standard JavaScript regex objects. The rest of the options only take effect if the match resolves to true.

Path Mapping: options.path

The options.path parameter is either a string or a function. When path is a string, a 1:1 replacement is made when the match is satisfied. When path is a function, it is invoked, receiving the current working path as a parameter for modification. For example, you can mount jQuery to a specific URL

Inject.addRule(/^jquery$/, {
  path: '/path/to/jquery-1.8.2.min.js'
});

or you can capture jquery ui components and mount those based on their naming convention

Inject.addRule(/^jquery\.ui\..+$/, {
  path: function (path) {
  	// sample: jquery.ui.button
  	var pieces = path.split('.');
  	pieces.shift(); // remove jquery
  	pieces.shift(); // remove ui

  	// that leaves just the jquery ui module
  	return '/path/to/jqueryui/' + pieces.join('.') + '.js';
  }
});

Whatever string is returned from the path function will become the new path.

Controlling Order: options.weight and options.last

The options.weight is an Integer value used to increase the priority of a rule. By default, rules are applied in a LIFO (last-in-first-out) manner. If you want a rule to “stick”, you can assign it a higher weight. Consider the contrived example

Inject.addRule(/^.+$/ {
  path: 'foo',
  weight: 100
});

Inject.addRule(/^.+$/ {
  path: 'bar'
});

The above will result in a resolution to “bar”. The default order would have been bar then foo, ultimately replacing everything with “foo”. However, the new weights put foo in position to resolve first, making the rule stick at the front.

The options.last tells Inject that no more rules should run after this. Coupled with options.weight, it’s a very effective way to stop a rules queue if required. An alternative syntax lets you specify weight in the method signature itself.

Controlling Automated Adjustment: options.useSuffix

Unless disabled as part of Inject.setUseSuffix, options.useSuffix allows a specific rule to disable the automatic suffix injection. If set to false explicitly, a “.js” suffix will be omitted.

Altering the File: options.pointcuts

options.pointcuts provides a way to modify the file after its download, but before execution. This enables you to alter a file to add require statements, assign module exports, and more without altering the original file. This “shimming” process is one of Inject’s biggest uses. There’s a list of receipies that demonstrate how to use pointcuts.

The before pointcut options.pointcuts.before (deprecated 0.4.1) and after pointcut options.pointcuts.after (deprecated 0.4.1) can be used to add function code before and after the file

Inject.addRule(/regex/, {
  pointcuts: {
    before: function () {
      // this code is injected before...
      var foo = 7;
    },
    after: function () {
      // this code is injected after...
      module.exports = window.Foo;
    }
  }
});

The after pointcut options.pointcuts.afterFetch (available 0.4.1) allow asynchronous manipulation of the file. The afterFetch pointcut takes a function with 4 parameters:

  • next - a function that passes control to the next function, call as next(err, newText)
  • text - the incoming text from previous afterFetch calls
  • moduleName - the name of the currently executing module
  • requestorName - the name of the module who made this request (parent module)
Inject.addRule(/regex/, {
  pointcuts: {
    afterFetch: function (next, text, moduleName, requestorName) {
      // modify "text" however you would like. When complete, call
      // next(null, result) for success
      // next(error) for failure
      next(null, text);
    }
  }
});

If you add additional require() statements using afterFetch, they will be added as dependencies. This makes it very easy to support things like JQuery UI and Dust Plugins.

comments powered by Disqus