模塊標(biāo)識是一個字符串,用來標(biāo)識模塊。在 require
、 require.async
等加載函數(shù)中,第一個參數(shù)都是模塊標(biāo)識。
Sea.js 中的模塊標(biāo)識是 CommonJS 模塊標(biāo)識 的超集:
一個模塊標(biāo)識由斜線(/
)分隔的多項組成。
每一項必須是小駝峰字符串、 .
或 ..
。
模塊標(biāo)識可以不包含文件后綴名,比如 .js
。
模塊標(biāo)識可以是 相對 或 頂級 標(biāo)識。如果第一項是 .
或 ..
,則該模塊標(biāo)識是相對標(biāo)識。
頂級標(biāo)識根據(jù)模塊系統(tǒng)的基礎(chǔ)路徑來解析。
相對標(biāo)識相對 require
所在模塊的路徑來解析。
注意,符合上述規(guī)范的標(biāo)識肯定是 Sea.js 的模塊標(biāo)識,但 Sea.js 能識別的模塊標(biāo)識不需要完全符合以上規(guī)范。 比如,除了大小寫字母組成的小駝峰字符串,Sea.js 的模塊標(biāo)識字符串還可以包含下劃線(_
)和連字符(-
), 甚至可以是 http://
、https://
、file:///
等協(xié)議開頭的絕對路徑。
相對標(biāo)識以 .
開頭,只出現(xiàn)在模塊環(huán)境中(define
的 factory
方法里面)。相對標(biāo)識永遠(yuǎn)相對當(dāng)前模塊的 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
頂級標(biāo)識不以點(.
)或斜線(/
)開始, 會相對模塊系統(tǒng)的基礎(chǔ)路徑(即 Sea.js 的 base
路徑)來解析:
// 假設(shè) base 路徑是:http://example.com/assets/// 在模塊代碼里:require.resolve('gallery/jquery/1.9.1/jquery'); // => http://example.com/assets/gallery/jquery/1.9.1/jquery.js
模塊系統(tǒng)的基礎(chǔ)路徑即 base
的默認(rèn)值,與 sea.js
的訪問路徑相關(guān):
如果 sea.js 的訪問路徑是: http://example.com/assets/sea.js 則 base 路徑為: http://example.com/assets/
當(dāng) sea.js
的訪問路徑中含有版本號時,base
不會包含 seajs/x.y.z
字串。 當(dāng) sea.js
有多個版本時,這樣會很方便。
如果 sea.js 的路徑是: http://example.com/assets/seajs/1.0.0/sea.js 則 base 路徑是: http://example.com/assets/
當(dāng)然,也可以手工配置 base
路徑:
seajs.config({
base: 'http://code.jquery.com/'});// 在模塊代碼里:require.resolve('jquery'); // => http://code.jquery.com/jquery.js
除了相對和頂級標(biāo)識之外的標(biāo)識都是普通路徑。普通路徑的解析規(guī)則,和 HTML 代碼中的 <script src="..."></script>
一樣,會相對當(dāng)前頁面解析。
// 假設(shè)當(dāng)前頁面是 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.jsseajs.use('../d'); // => 加載的是 http://example.com/path/to/d.js
提示:
頂級標(biāo)識始終相對 base
基礎(chǔ)路徑解析。
絕對路徑和根路徑始終相對當(dāng)前頁面解析。
require
和 require.async
中的相對路徑相對當(dāng)前模塊路徑來解析。
seajs.use
中的相對路徑始終相對當(dāng)前頁面來解析。
Sea.js 在解析模塊標(biāo)識時, 除非在路徑中有問號(?
)或最后一個字符是井號(#
),否則都會自動添加 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// 當(dāng)路徑中有問號("?")時,不會自動添加后綴:require.resolve('http://example.com/js/a.json?callback=define'); // => http://example.com/js/a.json?callback=define// 當(dāng)路徑以井號("#")結(jié)尾時,不會自動添加后綴,且在解析時,會自動去掉井號:require.resolve('http://example.com/js/a.json#'); // => http://example.com/js/a.json
模塊標(biāo)識的規(guī)則就上面這些,設(shè)計的核心出發(fā)點是:
關(guān)注度分離。比如書寫模塊 a.js
時,如果需要引用 b.js
,則只需要知道 b.js
相對 a.js
的相對路徑即可,無需關(guān)注其他。
盡量與瀏覽器的解析規(guī)則一致。比如根路徑(/xx/zz
)、絕對路徑、以及傳給 use
方法的非頂級標(biāo)識,都是相對所在頁面的 URL 進(jìn)行解析。
一旦理解了以上兩點,一切都會很自然、很簡單。不必刻意去記這些規(guī)則,多寫寫,自然就會。
更多建議: