简体   繁体   English

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

[英]Requirejs why and when to use shim config

I read the requirejs document 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 shim part 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.谢谢。

A primary use of shim is with libraries that don't support AMD, but you need to manage their dependencies. shim 的主要用途是用于不支持 AMD 的库,但您需要管理它们的依赖项。 For example, in the Backbone and Underscore example above: you know that Backbone requires Underscore, so suppose you wrote your code like this:例如,在上面的 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 first so 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.注意:这个下划线/主干示例是在这两个库都支持 AMD 之前编写的。 But the principle holds true for any libraries today that don't support AMD.但该原则适用于当今任何不支持 AMD 的库。

The "init" hook lets you do other advanced things, eg if a library would normally export two different things into the global namespace but you want to redefine them under a single namespace. “init”钩子可以让你做其他高级的事情,例如,如果一个库通常会将两个不同的东西导出到全局命名空间,但你想在单个命名空间下重新定义它们。 Or, maybe you want to do some monkey patching on a methods in the library that you're loading.或者,也许您想对正在加载的库中的方法进行一些猴子修补。

More background:更多背景:

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).假设您有 2 个 javascript 模块(moduleA 和 moduleB),其中一个(moduleA)依赖于另一个(moduleB)。 Both of these are necessary for your own module so you specify the dependencies in require() or define()这两个对于您自己的模块都是必需的,因此您可以在 require() 或 define() 中指定依赖项

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

But since require itself follow AMD, you have no idea which one would be fetched early.但是由于 require 本身跟随着 AMD,你不知道哪个会提前获取。 This is where shim comes to rescue.这就是 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. Shim 导出告诉 RequireJS 全局对象(窗口,当然,假设您在浏览器中)上的哪个成员是实际的模块值。 Lets say moduleA adds itself to the window as 'modA'(just like jQuery and underscore does as $ and _ respectively), then we make our exports value 'modA'.假设 moduleA 将自己作为“modA”添加到window中(就像 jQuery 和下划线分别作为 $ 和 _ 那样),然后我们将导出值设为“modA”。

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

It will give RequireJS a local reference to this module.它会给 RequireJS 一个对这个模块的本地引用。 The global modA will still exist on the page too.全局 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.尽管这两个函数都在窗口范围内可用,但 RequireJS 建议我们通过它们的全局标识符/句柄来使用它们以避免混淆。 So configuring the shim as所以将垫片配置为

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. init 函数的返回值用作模块导出值,而不是通过“exports”字符串找到的对象。 This will allow us to use funcB in our own module as这将允许我们在我们自己的模块中使用 funcB 作为

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

Hope this helped.希望这有帮助。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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