要求为什么以及何时使用shimconfiguration

我从这里读取了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(); } } } }); 

但我没有得到它的一部分。 为什么我应该使用垫片,我应该如何configuration,我可以得到一些更多的澄清

请用任何一个例子来解释为什么和什么时候应该使用垫片。 谢谢。

shim主要用于不支持AMD的库,但是您需要pipe理它们的依赖关系。 例如,在上面的Backbone和Underscore示例中:你知道Backbone需要Underscore,所以假设你这样写了你的代码:

 require(['underscore', 'backbone'] , function( Underscore, Backbone ) { // do something with Backbone } 

RequireJS将启动对Underscore和Backbone的asynchronous请求,但是您不知道哪一个会先回来,所以Backbone可能会在加载之前尝试使用Underscore执行某些操作。

注意:这个下划线/主干的例子是在这两个库支持AMD之前编写的。 但是,这个原则适用于任何不支持AMD的图书馆。

“init”钩子可以让你做其他高级的事情,例如,如果一个库通常将两个不同的东西导出到全局命名空间中,但是你想在一个命名空间下重新定义它们。 或者,也许你想在你正在加载的库中的某个方法上做一些修补程序。

更多背景:

  • 升级到RequireJS 2.0给出了订单插件如何试图解决这个问题的一些历史。
  • 请参阅Aaron Hardy撰写的本文的“加载非模块”一节, 以获得更好的描述。

根据RequireJS API文档,shim可以让你

configuration不使用define()声明依赖关系并设置模块值的较旧的传统“浏览器全局”脚本的依赖项,导出和自定义初始化。

– configuration依赖关系

假设你有2个JavaScript模块(moduleA和moduleB),其中一个(moduleA)依赖于另一个(moduleB)。 这两个都是你自己的模块所必需的,所以你可以在require()或define()

 require(['moduleA','moduleB'],function(A,B ) { ... } 

但是因为要求自己跟随AMD,所以你不知道哪一个会被提早取得。 这是垫片来救援的地方。

 require.config({ shim:{ moduleA:{ deps:['moduleB'] } } }) 

这将确保moduleB总是在moduleA加载之前获取。

– configuration导出

Shim导出告诉RequireJS全局对象上的成员(窗口,当然假设你在浏览器中)是实际的模块值。 比方说,moduleA将自己添加到window为'modA'(就像jQuery和下划线分别为$和_),然后我们使我们的出口值'modA'。

 require.config({ shim:{ moduleA:{ exports:'modA' } } 

它会给RequireJS一个本地引用这个模块。 全球的modA仍然会在页面上存在。

定制初始化旧的“浏览器全局”脚本

这可能是shim config最重要的特性,它允许我们在自己的模块中添加“浏览器全局”,“非AMD”脚本(不遵循模块化模式)作为依赖关系。

让我们说moduleB是简单的旧JavaScript只有两个函数funcA()和funcB()。

 function funcA(){ console.log("this is function A") } function funcB(){ console.log("this is function B") } 

虽然这两个函数在窗口范围内都可用,但RequireJSbuild议我们通过它们的全局标识符/句柄来使用它们,以避免混淆。 因此configuration垫片为

 shim: { moduleB: { deps: ["jquery"], exports: "funcB", init: function () { return { funcA: funcA, funcB: funcB }; } } } 

init函数的返回值用作模块导出值,而不是通过“exports”stringfind的对象。 这将允许我们在我们自己的模块中使用funcB

 require(["moduleA","moduleB"], function(A, B){ B.funcB() }) 

希望这有助于。

您必须在requirejs.config中添加path来声明,例如:

 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(); } } } });