常見問題:RequireJS 進階用法

如何重新命名 require/define/requirejs?§ 1

RequireJS 及其最佳化工具需要版本 0.26.0 或更高才能執行此操作。

為何您想這麼做?您可能對全域命名空間有非常嚴格的要求,或者您可能正在使用已定義 require/define 的程式碼,而您想避免干擾。

此功能的一些注意事項

  • 請務必使用 require.js 的原始版本,而不是壓縮版本。
  • 請務必將 require.js 版本包含在最佳化中,因為 require.js 檔案內容會因為命名空間而有所變更。
  • 使用 require/define 編寫您的模組,然後建立命名空間的值。請勿使用命名空間的 require/define 編寫您的模組。這會讓您的程式碼較不具可攜性和可用性。
  • 此轉換/最佳化只會執行一次。請勿將此最佳化的輸出作為另一個最佳化/建立階段的輸入。

下列範例最佳化設定是根據 最佳化頁面 中範例所使用的目錄結構。此設定將 require.js 與 main.js 結合為新的 foo.js 檔案。define() 重新命名為 foo.define(),而 require() 重新命名為 foo.require()


{
    appDir: "../",
    baseUrl: "scripts",
    dir: "../../appdirectory-build",

    //Put in a mapping so that 'requireLib' in the
    //modules section below will refer to the require.js
    //contents.
    paths: {
        requireLib: 'require'
    },

    //Indicates the namespace to use for require/requirejs/define.
    namespace: "foo",

    modules: [
        {
            name: "foo",
            include: ["requireLib", "main"],
            //True tells the optimizer it is OK to create
            //a new file foo.js. Normally the optimizer
            //wants foo.js to exist in the source directory.
            create: true
        }
    ]
}

完成此最佳化後,用於參照 require.js 的 HTML 需要修改為參照 foo.js。

感謝 Ryan Florence 在命名空間設計上的協助。


另一種重新命名的做法,如果您希望更直接地控制內容,並希望提交已修改的原始程式碼。此做法不應與上述示範的「命名空間」最佳化一起使用。

1) 修改 require.js 的原始程式碼

需要在 require.js 程式碼周圍建立一個包裝函式,以便您可以將 require 函式設定為您選擇的名稱

var myGlobalRequire = (function () {
    //Define a require object here that has any
    //default configuration you want for RequireJS. If
    //you do not have any config options you want to set,
    //just use an simple object literal, {}. You may need
    //to at least set baseUrl.
    var require = {
        baseUrl: '..'
    };

    //INSERT require.js CONTENTS HERE

    return require;
}());

2) 修改已載入的檔案

對於您使用此新函式載入的任何檔案,如果這些檔案以任何方式參照 require,您會希望將它們包裝在匿名函式中,以將 require 的值設定為您在步驟 1 中設定的新函式名稱

(function (require) {

    //Regular require references now work correctly in here.

}(myGlobalRequire));

按照上述步驟,您應該可以使用最佳化工具有效地將指令碼組合在一起。如果您希望在最佳化指令碼中重新命名 require 定義,請直接在 include 最佳化選項中參照您修改過的 require.js,或者如果您想直接最佳化該檔案,請作為 name 選項參照。

感謝 Alex SextonTobie Langel 建議此解決方案的部分內容。

關於載入 CSS 呢?§ 2

理想上,RequireJS 可以將 CSS 檔案載入為相依性。然而,在知道 CSS 檔案何時載入時會產生問題,特別是在從其他網域載入檔案時,在 Gecko/Firefox 中更是如此。一些歷史可以從 這個 Dojo 票證 中找到。

知道檔案何時載入很重要,因為您可能只想要在樣式表載入後取得 DOM 元素的尺寸。

有些人實作了一種方法,他們尋找一個眾所周知的樣式套用於特定的 HTML 元素,以了解樣式表是否已載入。由於該解決方案的特殊性,這並非能與 RequireJS 契合良好的做法。知道連結元素何時載入所引用的檔案將會是最穩健的解決方案。

由於無法可靠地知道檔案何時載入,因此在 RequireJS 載入中明確支援 CSS 檔案沒有意義,因為這會導致由於瀏覽器行為而產生的錯誤報告。如果您不在乎檔案何時載入,您可以輕鬆撰寫自己的函式,透過執行下列動作來依需求載入 CSS

function loadCss(url) {
    var link = document.createElement("link");
    link.type = "text/css";
    link.rel = "stylesheet";
    link.href = url;
    document.getElementsByTagName("head")[0].appendChild(link);
}