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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15471088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 00:53:05  来源:igfitidea点击:

Requirejs why and when to use shim config

javascriptrequirejsamdshimes5-shim

提问by Anil Gupta

I read the requirejsdocument from here API

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

but i am not getting shimpart of it. why should i use shim and how should i configure, can i get some more clarification

但我没有得到垫片的一部分。为什么我应该使用 shim 以及我应该如何配置,我能得到更多说明吗

please can any one explain with example why and when should we use shim. thanks.

请任何人举例解释为什么以及何时应该使用垫片。谢谢。

回答by explunit

A primary use of shim is with libraries that don't support AMD, but you need to manage their dependencies. For example, in the Backbone and Underscore example above: you know that Backbone requires Underscore, so suppose you wrote your code like this:

shim 的主要用途是与不支持 AMD 的库一起使用,但您需要管理它们的依赖项。例如,在上面的 Backbone 和 Underscore 示例中:您知道 Backbone 需要 Underscore,因此假设您这样编写代码:

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

    // do something with Backbone

}

RequireJS will kick off asynchronous requests for both Underscore and Backbone, but you don't know which one will come back firstso it's possible that Backbone would try to do something with Underscore before it's loaded.

RequireJS 将启动对 Underscore 和 Backbone 的异步请求,但您不知道哪个会先返回,因此 Backbone 可能会在 Underscore 加载之前尝试对其执行某些操作。

NOTE:this underscore/backbone example was written before both those libraries supported AMD. But the principle holds true for any libraries today that don't support AMD.

注意:这个下划线/主干示例是在这两个库都支持 AMD 之前编写的。但该原则适用于当今任何不支持 AMD 的库。

The "init" hook lets you do other advanced things, e.g. if a library would normally export two different things into the global namespace but you want to redefine them under a single namespace. Or, maybe you want to do some monkey patching on a methods in the library that you're loading.

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

More background:

更多背景:

回答by nalinc

As per RequireJS API documentation, shim lets you

根据 RequireJS API 文档,shim 允许您

Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value.

为较旧的传统“浏览器全局变量”脚本配置依赖项、导出和自定义初始化,这些脚本不使用 define() 来声明依赖项并设置模块值。

- Configuring dependencies

- 配置依赖

Lets say you have 2 javascript modules(moduleA and moduleB) and one of them(moduleA) depends on the other(moduleB). Both of these are necessary for your own module so you specify the dependencies in require() or define()

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

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

But since require itself follow AMD, you have no idea which one would be fetched early. This is where shim comes to rescue.

但是由于 require 本身跟随着 AMD,你不知道哪个会提前获取。这就是 shim 来拯救的地方。

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

})

This would make sure moduleB is always fetched before moduleA is loaded.

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

- Configuring exports

- 配置出口

Shim export tells RequireJS what member on the global object (the window, assuming you're in a browser, of course) is the actual module value. Lets say moduleA adds itself to the windowas 'modA'(just like jQuery and underscore does as $ and _ respectively), then we make our exports value 'modA'.

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

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

It will give RequireJS a local reference to this module. The global modA will still exist on the page too.

它会给 RequireJS 一个对这个模块的本地引用。全局 modA 仍将存在于页面上。

-Custom initialization for older "browser global" scripts

- 旧的“浏览器全局”脚本的自定义初始化

This is probably the most important feature of shim config which allow us to add 'browser global', 'non-AMD' scripts(that do not follow modular pattern either) as dependencies in our own module.

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

Lets say moduleB is plain old javascript with just two functions funcA() and funcB().

假设 moduleB 是一个简单的老式 javascript,只有两个函数 funcA() 和 funcB()。

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

Though both of these functions are available in window scope, RequireJS recommends us to use them through their global identifier/handle to avoid confusions. So configuring the shim as

尽管这两个函数都在窗口范围内可用,但 RequireJS 建议我们通过它们的全局标识符/句柄来使用它们以避免混淆。所以将垫片配置为

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

The return value from init function is used as the module export value instead of the object found via the 'exports' string. This will allow us to use funcB in our own module as

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

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

Hope this helped.

希望这有帮助。

回答by Rachman Anwar

You must add paths in requirejs.config to declare, example:

您必须在 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();
            }
        }
    }
});