seajs的模塊標識符和訪問規則

模塊標識是一個字符串,用來標識模塊。在 require、 require.async 等加載函數中,第一個參數都是模塊標識。
Sea.js 中的模塊標識是 CommonJS 模塊標識 的超集:

    1. 一個模塊標識由斜線(/)分隔的多項組成。
    2. 每一項必須是小駝峯字符串、 . 或 .. 。
    3. 模塊標識可以不包含文件後綴名,比如 .js 。
    4. 模塊標識可以是 相對 或 頂級 標識。如果第一項是 . 或 ..,則該模塊標識是相對標識。
    5. 頂級標識根據模塊系統的基礎路徑來解析。
    6. 相對標識相對 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

    1. 頂級標識始終相對 base 基礎路徑解析。
    2. 絕對路徑和根路徑始終相對當前頁面解析。
    3. require 和 require.async 中的相對路徑相對當前模塊路徑來解析。
    4. 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
設計原則:

設計的核心出發點是:


    1. 關注度分離。比如書寫模塊 a.js 時,如果需要引用 b.js,則只需要知道 b.js 相對 a.js 的相對路徑即可,無需關注其他。

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



一旦理解了以上兩點,一切都會很自然、很簡單。不必刻意去記這些規則,多寫寫,自然就會。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章