我从这里阅读 requirejs 文档api
requirejs.config({
shim: {
'backbone': {
//These script dependencies should be loaded before loading
//backbone.js
deps: ['underscore', 'jquery'],
//Once loaded, use the global 'Backbone' as the
//module value.
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'foo': {
deps: ['bar'],
exports: 'Foo',
init: function (bar) {
//Using a function allows you to call noConflict for
//libraries that support it, and do other cleanup.
//However, plugins for those libraries may still want
//a global. "this" for the function will be the global
//object. The dependencies will be passed in as
//function arguments. If this function returns a value,
//then that value is used as the module export value
//instead of the object found via the 'exports' string.
return this.Foo.noConflict();
}
}
}
});
但我没有得到 shim 的一部分。 为什么我应该使用垫片,我应该如何配置,我可以得到更多的澄清
请任何人解释为什么以及什么时候应该使用垫片。 感谢。
答案 0 :(得分:109)
shim的主要用途是不支持AMD的库,但您需要管理它们的依赖项。例如,在上面的Backbone和Underscore示例中:您知道Backbone需要Underscore,所以假设您编写了这样的代码:
require(['underscore', 'backbone']
, function( Underscore, Backbone ) {
// do something with Backbone
}
RequireJS将启动对Underscore和Backbone的异步请求,但是你不知道哪一个会先回来所以Backbone可能会在加载之前尝试使用Underscore。
注意:此下划线/骨干示例是在这两个库支持AMD之前编写的。但是这个原则适用于今天不支持AMD的任何图书馆。
“init”钩子可以让你做其他高级的事情,例如如果一个库通常会将两个不同的东西导出到全局命名空间中,但是你想在一个命名空间下重新定义它们。或者,也许你想对你正在加载的库中的方法做一些猴子修补。
更多背景资料:
答案 1 :(得分:62)
根据RequireJS API文档,shim允许你
配置依赖项,导出和自定义初始化 旧的,传统的"浏览器全局"不使用define()的脚本 声明依赖项并设置模块值。
- 配置依赖关系
假设您有2个javascript模块(moduleA和moduleB),其中一个(moduleA)依赖于另一个(moduleB)。这两个对于您自己的模块都是必需的,因此您可以在require()或define()
中指定依赖项require(['moduleA','moduleB'],function(A,B ) {
...
}
但是由于要求自己跟随AMD,你不知道哪个会提前获取。这就是垫片拯救的地方。
require.config({
shim:{
moduleA:{
deps:['moduleB']
}
}
})
这将确保在加载moduleA之前始终获取moduleB。
- 配置导出
Shim导出告诉RequireJS全局对象上的哪个成员(当然,假设您在浏览器中的窗口)是实际的模块值。假设moduleA将自己添加到window
作为' modA'(就像jQuery和下划线分别为$和_),然后我们将导出值设为' modA'。
require.config({
shim:{
moduleA:{
exports:'modA'
}
}
它将为RequireJS提供本模块的本地引用。全局modA也将存在于页面上。
- 旧版"浏览器全局"的自定义初始化脚本强>
这可能是shim配置最重要的功能,它允许我们添加浏览器全局'非AMD'脚本(不遵循模块化模式)作为我们自己模块中的依赖项。
让我们说moduleB是普通的旧javascript,只有两个函数funcA()和funcB()。
function funcA(){
console.log("this is function A")
}
function funcB(){
console.log("this is function B")
}
尽管这些功能在窗口范围内都可用,但RequireJS建议我们通过其全局标识符/句柄使用它们以避免混淆。所以将垫片配置为
shim: {
moduleB: {
deps: ["jquery"],
exports: "funcB",
init: function () {
return {
funcA: funcA,
funcB: funcB
};
}
}
}
init函数的返回值用作模块导出值,而不是通过' exports'串。这将允许我们在我们自己的模块中使用funcB作为
require(["moduleA","moduleB"], function(A, B){
B.funcB()
})
希望这会有所帮助。
答案 2 :(得分:-3)
您必须在requirejs.config中添加路径以声明,例如:
requirejs.config({
paths: {
'underscore' : '.../example/XX.js' /// your file java script
'jquery' : '.../example/jquery.js' /// your file java script
}
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'foo': {
deps: ['bar'],
exports: 'Foo',
init: function (bar) {
return this.Foo.noConflict();
}
}
}
});