繁体   English   中英

Requirejs 为什么以及何时使用 shim 配置

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM