about 4 years ago

紀錄首次使用時,記下的一些筆記、一些坑。

Reading Notes

  • 避免使用全域變數,非不得已,可以使用 shim 來建立你的全域變數

    Ideally the scripts you load will be modules that are defined by calling define(). However, you may need to use some traditional/legacy "browser globals" scripts that do not express their dependencies via define(). For those, you can use the shim config. To properly express their dependencies.

  • 以 module ID 命名。建議使用相對位置並去除副檔名 .js

    If a module ID has one of the following characteristics, the ID will not be passed through the "baseUrl + paths" configuration, and just be treated like a regular URL that is relative to the document:

    • Ends in ".js".
    • Starts with a "/".
    • Contains an URL protocol, like "http:" or "https:".

require.config

在開始使用 RequireJS 前,可以利用 config 先作一些定義。

paths

利用 paths 可以

  1. 替 script 建立 module ID ,可以簡化後續 import 使用的名稱。
  2. 縮短路徑名稱

例:

main.js
require.config({
    paths: {
      "js": "../js",  // 重新定義 js 所代表的路徑。

      "jquery": 'jquery/jquery.min',  // 以後 jquery/jquery.min 只要用 jquery 代替即可

      "bootstrap": "bootstrap/dist/js/bootstrap"
    }
});
shim
  1. export - 希望一個物件被視為全域變數時,可以利用 export 參數。

    main.js
    require.config({
        shim: {
            /*
            "Module ID": {
                export: "Object Name"
            }
            */
            sprintf: {
                export: "sprintf"
            }
        }
    });
    
    sprintf.js
    var sprintf = (function() {
            ...
    })();
    

    上例,只要是 sprintf module 被 import 的地方,其 script 裡面的 sprintf 物件會被視為全域變數。

  2. dependency - 對於無法獨自存在的 module,可以透過 dep 來設定。

    main.js
    require.config({
    shim: {
    /*
    "Module ID": {
    dep: ["Dependent Module"]
    }
    */

    bootstrap: {
    dep: ["jquery"]
    }
    }
    });



    上例,因為 bootstrap 是基於 jquery 的 module,所以必須特別設定相依關係。

    Some Gotcha

    1. 每一個 define 只會被執行一次。重複 define 只會得到上次的結果。
      所以要特別留意回傳的是類別還是實體。

    2. 同一頁的連續 script 要小心執行順序未必如您預期。例如:

      <script data-main="js/main" src="/static/require.js"></script>
      <script>
        require(["jquery"], function($){
            $('a[data-toggle=tooltip]').tooltip();
        });
      </script>
      

      通常會出現錯誤

      Failed to load resource: the server responded with a status of 404 (Not Found) 
      https://localhost:8080/js/jquery.js
      

      原因是 RequireJS 對於 script 的載入是非同步的,因此在 main.js 註冊的 jquery 名稱,會因尚未載入而無法被使用。他會認為這是一個新的 script 而直接使用路徑參照。

    參考資料

    1. RequireJS API
    2. jquery - Implementing AMD in JavaScript using RequireJS - Stack Overflow
    3. javascript - Require.js ignoring baseUrl - Stack Overflow
    4. Require.js 2.0 Shim Configuration
← Bootstrap 3 升級筆記 Docker 小試身手 →
 
comments powered by Disqus