I'm trying to use/load UnderscoreJS
1.7.0
with RequireJS
2.1.14-3
. At my application startup, UnderscoreJS is well loaded, but it is "undefined". See details below:
main.js
define(function() {
// Configuration of RequireJS
requirejs.config({
enforceDefine : true,
map : {
'*': {
...
'underscore' : 'webjars/underscorejs/1.7.0/underscore'
},
},
// The base URL is just the top-level directory where the files are stored
baseUrl : './',
// Kick-start the application by loading these files
deps : [ 'MyPanel' ],
});
});
The module using it :
define(['ractive',
'underscore',
...],
function(Ractive,
_,
...){
var Foo = Ractive.extend({
...
oninit: function(){
var anArray = [1, 2, 3]
_.each(anArray, function(item){
...
})
}
}
And the result in the browser console :
The underscoreJS file is loaded by the browser:
This must be a detail, but I managed my Javascript
dependencies with maven
and webjars
So why is my _
undefined
?
If you look at the source of Underscore 1.7.0, you see it registers itself like this:
if (typeof define === 'function' && define.amd) {
define('underscore', [], function() {
return _;
});
}
Note the first argument to define
. This hardcodes the name of the module as 'underscore'
.
The problem is that you are using a map
configuration which is not compatible with this hardcoded name. What you do is tell RequireJS "in all modules ("*"
), when the module requires a module with the name 'underscore'
, then please return instead the module with the name 'webjars/underscorejs/1.7.0/underscore'
". So when you require 'underscore'
:
RequireJS looks for the module named 'webjars/underscorejs/1.7.0/underscore'
instead.
It uses the default path for such a module name and finds a file at that location. It loads the file and executes it.
However, the file contains a define
calls that defines 'underscore'
, not 'webjars/underscorejs/1.7.0/underscore'
. So RequireJS is not able to honor the request.
Instead of map
, you should be using a paths
configuration for Underscore. Something like:
paths : {
'underscore' : 'webjars/underscorejs/1.7.0/underscore'
}
This tells RequireJS something like "you'll find the module named 'underscore'
at the location 'webjars/underscorejs/1.7.0/underscore'
". When you use this, the name of the module requested and the name of the module defined match.