簡體   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