Sea.js 的模塊遵循 CMD 規(guī)范,與 Node.js 的模塊規(guī)范非常相近,兩者的模塊可以很容易互相遷移。
非常簡(jiǎn)單。首先需要安裝 seajs
的 Node 模塊:
$ npm install seajs -g
安裝好后,在需要調(diào)用 Sea.js 模塊的入口文件里,require
下 seajs
:
a.js
define(function(require, exports) { exports.name = 'A';
});
main.js
require('seajs');var a = require('./a');console.log(a.name);
這樣就可以在 Node 環(huán)境中運(yùn)行 Sea.js 的模塊了:
$ node main.js A
這個(gè)也很簡(jiǎn)單,將 Node 的模塊封裝成 CMD 模塊即可:
a.js
exports.name = 'A';
封裝成
define(function(require, exports) { exports.name = 'A';
});
這樣在瀏覽器端就可以通過(guò) Sea.js 來(lái)加載使用了:
seajs.use('./a', function(a) { console.log(a.name);
});
通過(guò)上面的例子可以看出,只要遵循 CMD 規(guī)范來(lái)書寫模塊代碼,就可以非常方便的同時(shí)運(yùn)行在瀏覽器端和服務(wù)器端。這是 CMD 中 C 字母的含義:Common(通用)。
這比 RequireJS 的 AMD 規(guī)范好很多。
但是,無(wú)論是 CMD 還是 AMD 規(guī)范,或者是未來(lái)的某個(gè) Modules/Cool 規(guī)范,一個(gè)模塊要想同時(shí)在不同環(huán)境下執(zhí)行,就得遵循以下前提條件:
不能調(diào)用瀏覽器端的私有特性。比如 attachEvent
之類的,除非你在 Node 端提前模擬好。
不能調(diào)用服務(wù)器端的私有特性。比如 process
對(duì)象,除非你在瀏覽器端自己實(shí)現(xiàn)一個(gè)類似的 process
對(duì)象。
只用不同規(guī)范中的交集。比如 CMD 中有 module.uri
屬性,但 Node 中沒(méi)有,要通用,就不能去調(diào)用這些有差異的接口。類似的,Node 端的 __filename
在瀏覽器端不存在,要通用的話,也不能調(diào)用。
其實(shí)上面這些嚴(yán)格要求,是 非常自然的。這就如瀏覽器兼容一樣,要寫出所有瀏覽器下都能跑的代碼,最好的方式是只用那些所有瀏覽器都支持的特性,不然你就得用 if ... else ...
去搞啦。
Node.js 與 Sea.js 在模塊接口上的主要差異如下:
Node.js 里,模塊文件里的 this === module.exports
;Sea.js 里,this === window
。
Node.js 里,模塊文件里的 return xx
會(huì)被忽略;Sea.js 里,return xx
等價(jià) module.exports = xx
。
Node.js 里,require
是懶加載 + 懶執(zhí)行的。在 Sea.js 里是提前加載好 + 懶執(zhí)行。
Sea.js 里,require(id)
中的 id
必須是字符串直接量。Node.js 里沒(méi)這個(gè)限制。
更多建議: