[英]Requirejs why and when to use shim config
我从这里API阅读了requirejs文档
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 以及我应该如何配置,我能得到更多说明吗
请任何人举例解释为什么以及何时应该使用垫片。 谢谢。
shim 的主要用途是用于不支持 AMD 的库,但您需要管理它们的依赖项。 例如,在上面的 Backbone 和 Underscore 示例中:您知道 Backbone 需要 Underscore,因此假设您这样编写代码:
require(['underscore', 'backbone']
, function( Underscore, Backbone ) {
// do something with Backbone
}
RequireJS 将启动对 Underscore 和 Backbone 的异步请求,但您不知道哪个会先返回,因此 Backbone 可能会在 Underscore 加载之前尝试对其执行某些操作。
注意:这个下划线/主干示例是在这两个库都支持 AMD 之前编写的。 但该原则适用于当今任何不支持 AMD 的库。
“init”钩子可以让你做其他高级的事情,例如,如果一个库通常会将两个不同的东西导出到全局命名空间,但你想在单个命名空间下重新定义它们。 或者,也许您想对正在加载的库中的方法进行一些猴子修补。
更多背景:
根据 RequireJS API 文档,shim 允许您
为旧的、传统的“浏览器全局变量”脚本配置依赖项、导出和自定义初始化,这些脚本不使用 define() 来声明依赖项并设置模块值。
- 配置依赖
假设您有 2 个 javascript 模块(moduleA 和 moduleB),其中一个(moduleA)依赖于另一个(moduleB)。 这两个对于您自己的模块都是必需的,因此您可以在 require() 或 define() 中指定依赖项
require(['moduleA','moduleB'],function(A,B ) {
...
}
但是由于 require 本身跟随着 AMD,你不知道哪个会提前获取。 这就是 shim 来拯救的地方。
require.config({
shim:{
moduleA:{
deps:['moduleB']
}
}
})
这将确保在加载 moduleA 之前始终获取 moduleB。
- 配置出口
Shim 导出告诉 RequireJS 全局对象(窗口,当然,假设您在浏览器中)上的哪个成员是实际的模块值。 假设 moduleA 将自己作为“modA”添加到window
中(就像 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()
})
希望这有帮助。
您必须在 requirejs.config 中添加路径来声明,例如:
requirejs.config({
paths: {
'underscore' : '.../example/XX.js' // your JavaScript file
'jquery' : '.../example/jquery.js' // your JavaScript file
}
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'foo': {
deps: ['bar'],
exports: 'Foo',
init: function (bar) {
return this.Foo.noConflict();
}
}
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.