要求使用shim配置的原因和时间

Ani*_*pta 96 javascript amd requirejs

我从这里读apirequirejs文件

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();
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

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

请任何人解释一下为什么以及何时应该使用垫片.谢谢.

exp*_*nit 109

垫片的主要用途是不支持AMD的库,但您需要管理它们的依赖关系.例如,在上面的Backbone和Underscore示例中:您知道Backbone需要Underscore,所以假设您编写了如下代码:

require(['underscore', 'backbone']
, function( Underscore, Backbone ) {

    // do something with Backbone

}
Run Code Online (Sandbox Code Playgroud)

RequireJS将启动对Underscore和Backbone的异步请求,但你不知道哪一个会先回来,所以Backbone可能会在加载之前尝试使用Underscore.

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

"init"钩子允许您执行其他高级操作,例如,如果库通常会将两个不同的东西导出到全局命名空间中,但您希望在单个命名空间下重新定义它们.或者,也许你想对你正在加载的库中的方法进行一些猴子修补.

更多背景:


nal*_*inc 63

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

为不使用define()声明依赖项并设置模块值的旧的传统"浏览器全局"脚本配置依赖项,导出和自定义初始化.

- 配置依赖项

假设您有2个javascript模块(moduleA和moduleB),其中一个(moduleA)依赖于另一个(moduleB).这两个对于您自己的模块都是必需的,因此您可以在require()或define()中指定依赖项

require(['moduleA','moduleB'],function(A,B ) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是由于要求自己遵循AMD,你不知道哪个会提前获取.这是垫片来救援的地方.

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

})
Run Code Online (Sandbox Code Playgroud)

这将确保在加载moduleA之前始终获取moduleB.

- 配置导出

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

require.config({
    shim:{
       moduleA:{
         exports:'modA'
        } 
    }
Run Code Online (Sandbox Code Playgroud)

它将为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")
}
Run Code Online (Sandbox Code Playgroud)

尽管这些功能都可以在窗口范围内使用,但RequireJS建议我们通过其全局标识符/句柄使用它们以避免混淆.所以将垫片配置为

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

init函数的返回值用作模块导出值,而不是通过'exports'字符串找到的对象.这将允许我们在我们自己的模块中使用funcB

require(["moduleA","moduleB"], function(A, B){
    B.funcB()
})
Run Code Online (Sandbox Code Playgroud)

希望这有帮助.

  • Niko Bellic是对的,出口被忽略了(我刚刚测试过).对象B是'init'部分中指定的函数返回的对象.如果你删除'init'部分,对象B将成为函数funcB,所以你只需要做B()而不是B.funcB().显然,在这种情况下,funcA将无法访问. (4认同)
  • 容易明白!一个问题:在最后一个例子中,"出口"属性是否被忽略了? (3认同)