How to mixin Underscore plugins in RequireJS?
asynchronous, dynamic-script-loading, javascript, requirejs, underscore.js
Solution
I don't know if it's the correct way, but I got it working by inverting things so that underscore depends on underscore.string. Also, this way you don't have to require underscore.string.
require.config({
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
deps: ['underscore.string'],
exports: '_',
init: function(UnderscoreString) {
_.mixin(UnderscoreString);
}
}
},
paths: {
'backbone' : 'lib/backbone',
'jquery' : 'lib/jquery/jquery',
'text' : 'lib/require/text',
'underscore' : 'lib/underscore',
'underscore.string' : 'lib/underscore.string'
}
});
.
Update: 3/14/2014
Underscore.js v1.6.0 brought back AMD compatibility and `init()` has been removed from RequireJS, so some refactoring is in order. To continue getting Underscore preloaded with Underscore.string I made a mixer module to pull them together.
New Require.js config
requirejs.config({
paths: {
'backbone' : '../lib/backbone/backbone',
'backbone.base' : '../lib/backbone/backbone.base',
'backbone.extensions' : '../lib/backbone/backbone.extensions',
'jquery' : '../lib/jquery/jquery',
'text' : '../lib/require/text',
'underscore' : '../lib/underscore/underscore',
'underscore.mixed' : '../lib/underscore/underscore.mixed',
'underscore.string' : '../lib/underscore/underscore.string'
},
shim: {
'backbone.base': {
deps: ['underscore.mixed', 'jquery'],
exports: 'Backbone'
},
}
});
underscore.mixed
define([
'underscore',
'underscore.string'
], function(_, _s) {
_.mixin(_s.exports());
return _;
});
The final step is to replace all instances of `'underscore'` with `'underscore.mixed'` in module definitions. I attempted moving Underscore into a file named `underscore.base.js` and making the regular `underscore` the mixer (like the Backbone setup) to avoid this step. Underscore, being a named module, disagreed with the plan.
Problem
What is the right way to execute code on Underscore when it gets loaded? I am trying to execute the below code to extend the _ exported namespace automatically when modules require it: ``` _.mixin(_.str.exports()); ``` The docs are a bit vague but I think I put it in the shim init section? I tried the below but I can't even get a breakpoint to hit in the init: ``` require.config({ paths: { jquery: 'libs/jquery/jquery.min', underscore: 'libs/underscore/lodash.min', underscorestring: 'libs/underscore/underscore.string.min' }, shim: { underscore: { exports: '_' } underscorestring: { deps: ['underscore'], init: function (_) { //Mixin plugin to namespace _.mixin(_.str.exports()); return _; } } } }); ``` When I try to do this and use underscorestring, I get this error: Uncaught TypeError: Object function s(e){return new o(e)} has no method 'startsWith' Docs: - http://requirejs.org/docs/api.html#config-shim - http://requirejs.org/docs/api.html#config-callback