seajs學習--module-id 規範

 你們相信如今已經可以用seajs完成一個項目了,可是此時的項目離正式上線還有不少差距,還需作不少優化,譬如,優化請求次數,優化文件大小。

當你使用seajs愉快的編碼的時候,你也就會發現模塊實在是太多了,請求數目過多這一問題。在這章,咱們來共同探討一下怎麼優化seajs工程,使之真正能夠達到能夠上線的標準。

在進行優化之前,咱們先討論一下seajs裏邊的模塊ID,還記得前面說過CMD的模塊定義嗎?define(id?deps?,factory),這裏邊的模塊ID,官方建議咱們不要寫,經過工具去生成,那麼你知道這個id是怎麼生成的,經過什麼規則呢?

這節咱們就來看看這個module ID。

先看看咱們會在哪裏都會用到module ID。三個地方,
    
    define(id[1],['id[2]'],function(require){
            var a = require("id"[3]);
    })

不管是define第一個參數【模塊ID】仍是第二個參數【依賴模塊的ID】仍是【require模塊ID】,最終的比對標準是【解析後的文件URI】。
所以,這三處須要寫ID 的地方能夠以任意一種方式來寫,只要最終解析爲同一個URI,即被認爲是同一個模塊。
    

Sea.js 的一個基本約定原則:**ID 和路徑匹配原則**。

所謂 **ID 和路徑匹配原則** 是指,使用 seajs.use 或 require 進行引用的文件,若是是具名模塊(即定義了 ID 的模塊),會把 ID 和 seajs.use 的路徑名進行匹配,若是一致,則正確執行模塊返回結果。反之,則返回 null。例如:

    define('path/module/a',[],function(require){
    
    })

    在該例中,模塊ID定義爲了path/moudle/a,那麼a模塊應該正確放置的位置就base(在config中定義的)/path/moudle/a.js,假如a.js不在該位置,則返回了null。
    
至於爲何` 必定要使用必定要把 ID 定爲文件路徑`,這一塊請移步 [https://github.com/seajs/seajs/issues/930
]()

###在詳細的討論下 Module_ID的解析規則

Sea.js 中的模塊標識是 CommonJS 模塊標識 的超集:

* 一個模塊標識由斜線(/)分隔的多項組成。
* 每一項必須是小駝峯字符串、 . 或 .. 。
* 模塊標識能夠不包含文件後綴名,好比 .js 。
* 模塊標識能夠是 相對 或 頂級 標識。若是第一項是 . 或 ..,則該模塊標識是相對標識。
* 頂級標識根據模塊系統的基礎路徑來解析。
* 相對標識相對 require 所在模塊的路徑來解析。

注意,符合上述規範的標識確定是 Sea.js 的模塊標識,但 Sea.js 能識別的模塊標識不須要徹底符合以上規範。 好比,除了大小寫字母組成的小駝峯字符串,Sea.js 的模塊標識字符串還能夠包含下劃線(_)和連字符(-), 甚至能夠是 http://、https://、file:/// 等協議開頭的絕對路徑。

相對標識

相對標識以 . 開頭,只出如今模塊環境中(define 的 factory 方法裏面)。相對標識永遠相對當前模塊的 URI 來解析:

    // 在 http://example.com/js/a.js 的 factory 中:
    require.resolve('./b');
      // => http://example.com/js/b.js

    // 在 http://example.com/js/a.js 的 factory 中:
    require.resolve('../c');
      // => http://example.com/c.js
    頂級標識

    頂級標識不以點(.)或斜線(/)開始, 會相對模塊系統的基礎路徑(即 Sea.js 的 base 路徑)來解析:

    // 假設 base 路徑是:http://example.com/assets/

    // 在模塊代碼裏:
    require.resolve('gallery/jquery/1.9.1/jquery');
      // => http://example.com/assets/gallery/jquery/1.9.1/jquery.js
  
模塊系統的基礎路徑即 base 的默認值,與 sea.js 的訪問路徑相關:

    若是 sea.js 的訪問路徑是:
      http://example.com/assets/sea.js

    則 base 路徑爲:
      http://example.com/assets/
    當 sea.js 的訪問路徑中含有版本號時,base 不會包含 seajs/x.y.z 字串。 當 sea.js 有多個版本時,這樣會很方便。

    若是 sea.js 的路徑是:
      http://example.com/assets/seajs/1.0.0/sea.js

    則 base 路徑是:
      http://example.com/assets/
    固然,也能夠手工配置 base 路徑:

    seajs.config({
      base: 'http://code.jquery.com/'
    });

    // 在模塊代碼裏:
    require.resolve('jquery');
      // => http://code.jquery.com/jquery.js
  
####普通路徑

除了相對和頂級標識以外的標識都是普通路徑。普通路徑的解析規則,和 HTML 代碼中的 <script src="..."></script> 同樣,會相對當前頁面解析。

    // 假設當前頁面是 http://example.com/path/to/page/index.html

    // 絕對路徑是普通路徑:
    require.resolve('http://cdn.com/js/a');
      // => http://cdn.com/js/a.js

    // 根路徑是普通路徑:
    require.resolve('/js/b');
      // => http://example.com/js/b.js

    // use 中的相對路徑始終是普通路徑:
    seajs.use('./c');
      // => 加載的是 http://example.com/path/to/page/c.js

    seajs.use('../d');
      // => 加載的是 http://example.com/path/to/d.js
      
提示:

頂級標識始終相對 base 基礎路徑解析。
絕對路徑和根路徑始終相對當前頁面解析。
require 和 require.async 中的相對路徑相對當前模塊路徑來解析。
seajs.use 中的相對路徑始終相對當前頁面來解析。
文件後綴的自動添加規則

Sea.js 在解析模塊標識時, 除非在路徑中有問號(?)或最後一個字符是井號(#),不然都會自動添加 JS 擴展名(.js)。若是不想自動添加擴展名,能夠在路徑末尾加上井號(#)。

    // ".js" 後綴能夠省略:
    require.resolve('http://example.com/js/a');
    require.resolve('http://example.com/js/a.js');
      // => http://example.com/js/a.js

    // ".css" 後綴不可省略:
    require.resolve('http://example.com/css/a.css');
      // => http://example.com/css/a.css

    // 當路徑中有問號("?")時,不會自動添加後綴:
    require.resolve('http://example.com/js/a.json?callback=define');
      // => http://example.com/js/a.json?callback=define

    // 當路徑以井號("#")結尾時,不會自動添加後綴,且在解析時,會自動去掉井號:
    require.resolve('http://example.com/js/a.json#');
      // => http://example.com/js/a.json
      
####設計原則

模塊標識的規則就上面這些,設計的核心出發點是:

關注度分離。好比書寫模塊 a.js 時,若是須要引用 b.js,則只須要知道 b.js 相對 a.js 的相對路徑便可,無需關注其餘。

儘可能與瀏覽器的解析規則一致。好比根路徑(/xx/zz)、絕對路徑、以及傳給 use 方法的非頂級標識,都是相對所在頁面的 URL 進行解析。css

相關文章
相關標籤/搜索