在 SeaJS 中,全部 JavaScript 文件都應該用模塊的形式來書寫,而且一個文件只包含一個模塊。數組
使用全局函數 define
來定義模塊:異步
define(id?, dependencies?, factory);
當前模塊的惟一標識。該參數可選。若是沒有指定,默認爲模塊所在文件的訪問路徑。若是指定的話, 必須是頂級或絕對標識(不能是相對標識)。async
當前模塊所依賴的模塊,是一個由模塊標識組成的數組。該參數可選。若是沒有指定,模塊加載器會從factory.toString()
中解析出該數組。ide
** 注意:強烈推薦不要設定 id
和 dependencies
參數。 在開發階段,模塊加載器會自動獲取這兩個參數。部署上線時,則能夠經過優化工具來提取這兩個參數。函數
模塊的工廠函數。模塊初始化時,會調用且僅調用一次該工廠函數。factory
能夠是函數, 也能夠是對象、字符串等任意值,這時 module.exports
會直接設置爲 factory
值。工具
factory
函數在調用時,會始終傳入三個參數: require
、exports
和 module
, 這三個參數在全部模塊代碼裏可用。優化
define(function(require, exports, module) { // The module code goes here });
exports
用來向外提供模塊的 API.ui
define(function(require, exports) { // snip... exports.foo = 'bar'; exports.doSomething = function() {}; });
除了給 exports
對象增長成員,還可使用 return
直接向外提供 API.this
define(function(require, exports) { // snip... return { foo: 'bar', doSomething: function() {}; }; });
若是 return
語句是模塊中的惟一代碼,可簡化爲:
define({ foo: 'bar', doSomething: function() {}; });
上面這種格式特別適合定義 JSON 數據。
** 注意:下面這種寫法是錯誤的!
define(function(require, exports) { // snip... exports = { // 錯誤! foo: 'bar', doSomething: function() {}; }; });
模塊加載器不能獲取到新賦給 exports
變量的值。 請使用 return
或 module.exports
。
require
函數用來訪問其餘模塊提供的 API.
define(function(require) { var a = require('./a'); a.doSomething(); });
它接受 模塊標識 做爲惟一參數。
請牢記,爲了使靜態分析能成功獲取到模塊依賴信息,在書寫模塊時,須要遵循一些簡單的 規則。
該方法可用來異步加載模塊,並在加載完成後執行回調函數。
define(function(require, exports, module) { // 加載一個模塊 require.async('./b', function(b) { b.doSomething(); }); // 加載多個模塊 require.async(['./c', './d'], function(c, d) { // do something }); });
使用 require()
的內部機制來解析並返回模塊路徑。該函數不會加載模塊,只返回解析後的路徑。
該方法可用來異步加載腳本,並在加載完成後,執行指定的回調函數。開發插件時, 能夠經過覆蓋該方法來實現自定義的資源加載。
有時候,咱們須要給全部 require
參數對象添加一些公用屬性或方法。這時, 使用 require.constructor
來實現會很是方便。
module
參數存儲模塊的元信息。擁有如下成員:
當前模塊的惟一標識。 require(module.id)
必然返回此模塊的 exports
。
define(function(require, exports, module) { console.log(module.id); // http://path/to/this/file.js console.log(require(module.id) === exports); // true });
module.dependencies
是一個數組,表示當前模塊的依賴列表。
該數組只讀:模塊加載完成後,修改該數組不會有任何效果。
exports
對象由模塊系統建立,這不能知足開發者的全部需求, 有時候會但願 exports
是某個類的實例。 這時可用 module.exports
來實現:
define(function(require, exports, module) { console.log(module.exports === exports); // true module.exports = new SomeClass(); console.log(module.exports === exports); // false });
注意,對 module.exports
的賦值須要同步執行,它不能放在回調函數裏。 下面這樣是不行的:
x.js:
define(function(require, exports, module) { setTimeout(function() { module.exports = { a: "hello" }; }, 0); });
y.js:
define(function(require, exports, module) { var x = require('./x'); console.log(x.a); // undefined });
有時候,咱們須要給全部 module
參數對象添加一些公用屬性或方法。在這種狀況下, 使用module.constructor
能夠很好地知足需求。
extend.js:
define(function(require, exports, module) { var Module = module.constructor; Module.prototype.filename = function() { var id = this.id; var parts = id.split('/'); return parts[parts.length - 1]; }; });
a.js:
define(function(require, exports, module) { exports.filename = module.filename(); });