国产chinesehdxxxx野外,国产av无码专区亚洲av琪琪,播放男人添女人下边视频,成人国产精品一区二区免费看,chinese丰满人妻videos

ID 和路徑匹配原則

2018-11-06 18:33 更新

經(jīng)常收到 seajs.use 某具名模塊時發(fā)現(xiàn)其引用為 null 的問題,或是移動了文件位置導(dǎo)致引用為 null 或者 object is not function 的問題。比如這個 #954 ,這個 #888 ,這個 #879 ,這個 #739 ,這個 #696 ,還有這個 seajs/examples#12 。

這些問題都指向 Sea.js 的一個基本約定原則:ID 和路徑匹配原則

這是什么

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

seajs.use('lib/jquery', function($) {    // use $});

或者在模塊中 require :

define(function(require, exports, module) {    var $ = require('lib/jquery');    // use $});

當(dāng) jQuery 文件是下面的情況時,上述的變量 $ 能拿到正確的返回結(jié)果。

// 文件路徑是 lib/jquery.js// ID 和實際路徑匹配了(.js 后綴會自動補上)define('lib/jquery', function(require, exports, module) {    // jquery code});

下面的代碼則返回 null:

// 文件路徑是 lib/jquery.js// 但是 ID 是 lib/jquery.min.js// ID 和路徑不匹配define('lib/jquery.min', function(require, exports, module) {    // jquery code});

而匿名模塊始終能正確返回結(jié)果:

// lib/jquery.js// 匿名模塊,不需要進(jìn)行匹配// 但是文件中只能有一個 define 塊define(function(require, exports, module) {    // jquery code});

注意這里用于匹配的 ID 都是經(jīng)過 alias 和 path 解析并且補完后綴之后的。

為什么要有這個原則

回答這個問題前,請先閱讀這篇文章:#426 。

首先,Sea.js 的模塊啟動接口秉承的是路徑即 ID 的設(shè)計原則。seajs.use 的方法的第一個參數(shù)被規(guī)定為文件路徑(而不是 ID),這樣的設(shè)計減輕了記憶模塊 ID 的負(fù)擔(dān),無論是匿名模塊還是具名模塊,開發(fā)者只需要知道文件放在哪兒就行了。

進(jìn)一步的,之所以有這個 ID 和路徑匹配原則,是因為在 CMD 的書寫規(guī)范中,一個文件對應(yīng)一個模塊,所有的模塊都是匿名模塊(即 define(factory) 的形式)。那么當(dāng) seajs.use 某模塊時,這個模塊對應(yīng)的文件里的唯一的 define 方法理所當(dāng)然的是這個模塊的執(zhí)行代碼,這時可以正確返回結(jié)果。

但是在生產(chǎn)環(huán)境下,靜態(tài)文件不可避免地需要進(jìn)行合并打包或者進(jìn)行 combo,以優(yōu)化請求數(shù)提高頁面性能。這時,一個 js 文件可能有很多 define() 方法。

define(funtion(require, exports, module) {    // module a});

define(funtion(require, exports, module) {    // module b});

define(funtion(require, exports, module) {    // module c});

那么請問,當(dāng) seajs.use 這個文件時,應(yīng)該返回哪個模塊?

所以這時候 ID 就派上了用場,我們可以這樣寫:

// path/a.jsdefine('path/a', funtion(require, exports, module) {    // module a});

define('path/b', funtion(require, exports, module) {    // module b});

define('path/c', funtion(require, exports, module) {    // module c});

我們定義好每個模塊的 id ,在 Sea.js 里,那個和文件路徑匹配的 ID 的模塊就是這個文件的主模塊。此時:

seajs.use('path/a', function(a) {    // got a, not b or c});

這個原則保證了我們能夠自由合并模塊來優(yōu)化性能,seajs-combospm-build 的構(gòu)建機制都是基于此原則。

在 RequireJS 中,也有類似的原則:http://requirejs.org/docs/errors.html#mismatch

更深一步

可能有人要問為啥一定要把 ID 定為文件路徑,Sea.js 不是可以自定義 ID 嗎,像下面這樣:

define('module-id', funtion(require, exports, module) {    // module id});// 然后就可以seajs.use('module-id', function(Module) {    // Module});

上面的代碼當(dāng)然可以運行。但是有一點,任何一個模塊的運行都涉及到兩個步驟:模塊定義模塊執(zhí)行,上面的代碼兩個步驟都包括在內(nèi)。而使用了 Sea.js ,我們不希望用戶去手動寫 script 標(biāo)簽引用模塊。希望只需要 seajs.use 模塊的文件路徑即可(入口唯一):

seajs.use('path/to/module', function(Module) {    // Module});

Sea.js 會自動插入 script 標(biāo)簽,完成定義步驟,然后執(zhí)行模塊,拿到模塊的輸出。所以當(dāng)一個文件里有多個 define 時,只能用 ID 是否匹配 use 中的路徑來判斷是否主模塊。

當(dāng)然可以回避掉這個原則,你只需要自己負(fù)責(zé)模塊的定義部分,再自己 seajs.use 之前定義好的模塊 ID 就行。

<!-- 各種模塊的定義 define define define --><script src="http://example.com/modules.js"></script><script>// 這時 use 的第一個參數(shù)就可以不必是文件路徑了,因為已經(jīng)有定義好的模塊 ID 了seajs.use('jquery', function($) {    // $});</script>

或者通過 alias 來幫助 ID 匹配上最終的路徑,這樣就和 RequireJS 的方案基本一致了。

  // lib/jquery-1.7.2.js 的內(nèi)容如下define('$', funtion(require, exports, module) {  // jQuery});

這樣就不需要自己去引用上面的文件,可以直接通過 seajs.use 調(diào)用。

seajs.config({
  alias: {
    $: 'lib/jquery-1.7.2.js'
  }
});

seajs.use('$', function() {  // Got $ !});

使用 spm-build 和 grunt 進(jìn)行打包

我們推薦使用配套的構(gòu)建工具來打包模塊。

在 spm-build 中,所有的匿名模塊通過標(biāo)準(zhǔn)的 transport 流程,會打包成具有實際 ID 的具名模塊,而主模塊(在 package.json 中指定輸出的文件)的 ID 和實際路徑是匹配的,符合ID 和路徑匹配原則。

如果沒有使用官方工具,你需要在自己的打包和部署過程中保證這個原則。

歷史

實際上在版本 1.3.1 之前,有一個特性叫做 firstModuleInPackage,即當(dāng)一個文件里有多個 define 時,默認(rèn)將第一個 define 里的模塊作為主模塊進(jìn)行返回。由于各種原因我們?nèi)サ袅诉@個特性,可以參見:#438。

小結(jié)

ID 和路徑匹配原則 是 Sea.js 實現(xiàn)中的一個約定,這個約定幫助我們減少了對 ID 的記憶負(fù)擔(dān),同時增加了構(gòu)建的復(fù)雜度。

同樣的,這也是一把雙刃劍,目前還沒有『完美』的處理方案,都會在某些地方存在取舍和權(quán)衡。如果這方面你有好的想法,歡迎與我們交流。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號