我正在尝试迁移网站以使用RequireJS来管理它的JS依赖项。我还想把一些lib捆绑在一起。
目前我们正在构建一个包含下划线,jquery,bootstrap和骨干的base.min.js
。它们在我们的网站上使用,因此将它们组合在一起是有意义的。
尽管如此,我认为我们应该逻辑上将三个库按名称分开,因此我编写了以下require.config:
require.config({
baseUrl: '/s/js/libs',
paths: {
app: '../app', shims: '../shims'
},
map: {
'*' : {
// underscore, backbone, jquery and bootstrap are bundled
'underscore': '../base',
'backbone': '../base',
'jquery': '../base',
'bootstrap': '../base'
}
},
shim:{
'bootstrap': {
deps: ['jquery']
},
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'jquery': {exports: '$'}
}
});
我没有使用data-main
;但相反,我需要几件事:
require(["jquery", "underscore", "backbone", "bootstrap", "../baseapp"],
function($){
// Next line fixes the bootstrap issue with double modals taken from:
// http://stackoverflow.com/questions/13649459/twitter-bootstrap-multiple-modal-error
$.fn.modal.Constructor.prototype.enforceFocus = function () {};
$('.modal').on('shown', function () {
$('input:text:visible:first, textarea:visible:first', this).focus();
});
$('#search').on('shown', function () {
$('#id_asf-text').focus();
})
require(['micro', 'csrf_xhr', 'locale']);
require(['app/routers']);
});
然而,这会导致$
未定义的错误。
定义了全局window.$
,但似乎requirejs未使用我的垫片exports
正确检测到它。即使我exports: 'window.jQuery'
它也不起作用。
这是RequireJS中的错误还是我的代码中有错误? map
和shim
一起玩得很好吗? RequireJS是否支持我的用例?
经过长时间的调试后,我发现在RequireJS中每个“真实”模块都记录了垫片;所以,如果我只是改变我的垫片:
shim : {
'../base': {init: function() {return [$, _, Backbone]}}
}
我确实将此数组作为回调的第一个参数。但是我希望它们能够爆炸,即;将每个返回的值作为参数...
我认为内部地图+路径可行。像这样:
var require = {
baseUrl: '/s/js/libs/',
paths: {
app: '../app',
shims: '../shims',
'base-underscore': '../base',
'base-backbone': '../base',
'base-jquery': '../base',
'base-bootstrap': '../base'
},
map: {
'*' : {
// underscore, backbone, jquery and bootstrap are bundled
'underscore': 'base-underscore',
'backbone': 'base-backbone',
'jquery': 'base-jquery',
'bootstrap': 'base-bootstrap',
}
},
shim:{
'base-bootstrap': {
deps: ['base-jquery'],
init: function() {return null}
},
'base-backbone': {
deps: ['base-underscore', 'base-jquery'],
init: function() {return window.Backbone;}
},
'base-underscore': {
init: function() {return window.Underscore;}
},
'base-jquery': {
init: function() {return $}
}
} // shims
};
不幸的是,事实并非如此。现在错误是:Uncaught Error: Load timeout for modules: base-underscore,base-backbone,base-bootstrap,../base
...注意没有列出base-jquery!
答案 0 :(得分:0)
我找到了一个解决方法,但涉及一个插件。这是我目前的解决方案。在我的HTML上,我有以下config
(我改为require = {...}
成语,以便调试更容易):
var STATIC_URL = "/s/js/libs/";
var require = {
baseUrl: STATIC_URL,
paths: {
app: '../app',
shims: '../shims',
},
map: {
'*': {
'jquery': 'bundler!jQuery',
'bootstrap': 'bundler!',
'underscore': 'bundler!_',
'backbone': 'bundler!Backbone'
}
},
bundler: {url: '../base'}
};
bundler.js
插件位于我的js/libs
。这是最初的CoffeeScript:
global = @
each = (ary, func) ->
if (ary)
i = 0
while i < ary.length and (what = ary[i]) and func(what, i, ary)
i += 1
getGlobal = (value) ->
if not value
value
g = global;
each value.split('.'), (part) ->
g = g[part]
g
define
load: (name, require, onload, config) ->
base = config.bundler?.url ? '../base'
require [base], () ->
if name? and name
value = getGlobal(name)
onload(value)
else
onload()
normalize: (name, norm) -> name
可能有一种方法可以在没有bundler
的情况下执行此操作...我会暂时保持问题,以便提供更好的答案。