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