CMD 模組定義規範

來源:互聯網
上載者:User

標籤:

在 Sea.js 中,所有 JavaScript 模組都遵循 CMD(Common Module Definition) 模組定義規範。該規範明確了模組的基本書寫格式和基本互動規則。

在 CMD 規範中,一個模組就是一個檔案。代碼的書寫格式如下:

define(factory);
define Function

define 是一個全域函數,用來定義模組。

define define(factory)

define 接受 factory 參數,factory 可以是一個函數,也可以是一個對象或字串。

factory 為對象、字串時,表示模組的介面就是該對象、字串。比如可以如下定義一個 JSON 資料模組:

define({ "foo": "bar" });

也可以通過字串定義模板模組:

define(‘I am a template. My name is {{name}}.‘);

factory 為函數時,表示是模組的構造方法。執行該構造方法,可以得到模組向外提供的介面。factory 方法在執行時,預設會傳入三個參數:require、exports 和 module:

define(function(require, exports, module) {  // 模組代碼});
define define(id?, deps?, factory)

define 也可以接受兩個以上參數。字串 id 表示模組標識,數組 deps 是模組依賴。比如:

define(‘hello‘, [‘jquery‘], function(require, exports, module) { // 模組代碼});

id 和 deps 參數可以省略。省略時,可以通過構建工具自動產生。

注意:帶 id 和 deps 參數的 define 用法不屬於 CMD 規範,而屬於 Modules/Transport 規範。

define.cmd Object

一個Null 物件,可用來判定當前頁面是否有 CMD 模組載入器:

if (typeof define === "function" && define.cmd) { // 有 Sea.js 等 CMD 模組載入器存在}
require Function

require 是 factory 函數的第一個參數。

require require(id)

require 是一個方法,接受 模組標識 作為唯一參數,用來擷取其他模組提供的介面。

define(function(require, exports) {  // 擷取模組 a 的介面  var a = require(‘./a‘); // 調用模組 a 的方法 a.doSomething();});

注意:在開發時,require 的書寫需要遵循一些 簡單約定。

require.async require.async(id, callback?)

require.async 方法用來在模組內部非同步載入模組,並在載入完成後執行指定回調。callback 參數可選。

define(function(require, exports, module) {  // 非同步載入一個模組,在載入完成時,執行回調 require.async(‘./b‘, function(b) { b.doSomething(); }); // 非同步載入多個模組,在載入完成時,執行回調 require.async([‘./c‘, ‘./d‘], function(c, d) { c.doSomething(); d.doSomething(); });});

注意:require 是同步往下執行,require.async 則是非同步回調執行。require.async 一般用來載入可延遲非同步載入的模組。

require.resolve require.resolve(id)

使用模組系統內部的路徑解析機制來解析並返回模組路徑。該函數不會載入模組,只返回解析後的絕對路徑。

define(function(require, exports) {  console.log(require.resolve(‘./b‘)); // ==> http://example.com/path/to/b.js});

這可以用來擷取模組路徑,一般用在外掛程式環境或需動態拼接模組路徑的情境下。

exports Object

exports 是一個對象,用來向外提供模組介面。

define(function(require, exports) {  // 對外提供 foo 屬性  exports.foo = ‘bar‘; // 對外提供 doSomething 方法 exports.doSomething = function() {};});

除了給 exports 對象增加成員,還可以使用 return 直接向外提供介面。

define(function(require) {  // 通過 return 直接提供介面  return {    foo: ‘bar‘, doSomething: function() {} };});

如果 return 語句是模組中的唯一代碼,還可簡化為:

define({  foo: ‘bar‘,  doSomething: function() {}});

上面這種格式特別適合定義 JSONP 模組。

特別注意:下面這種寫法是錯誤的!

define(function(require, exports) {  // 錯誤用法!!!  exports = { foo: ‘bar‘, doSomething: function() {} };});

正確的寫法是用 return 或者給 module.exports 賦值:

define(function(require, exports, module) {  // 正確寫法 module.exports = { foo: ‘bar‘, doSomething: function() {} };});

提示:exports 僅僅是 module.exports 的一個引用。在 factory 內部給 exports 重新賦值時,並不會改變 module.exports 的值。因此給 exports 賦值是無效的,不能用來更改模組介面。

module Object

module 是一個對象,上面儲存了與當前模組相關聯的一些屬性和方法。

module.id String

模組的唯一標識。

define(‘id‘, [], function(require, exports, module) { // 模組代碼});

上面代碼中,define 的第一個參數就是模組標識。

module.uri String

根據模組系統的路徑解析規則得到的模組絕對路徑。

define(function(require, exports, module) {  console.log(module.uri); // ==> http://example.com/path/to/this/file.js});

一般情況下(沒有在 define 中手寫 id 參數時),module.id 的值就是 module.uri,兩者完全相同。

module.dependencies Array

dependencies 是一個數組,表示當前模組的依賴。

module.exports Object

當前模組對外提供的介面。

傳給 factory 構造方法的 exports 參數是 module.exports 對象的一個引用。只通過 exports 參數來提供介面,有時無法滿足開發人員的所有需求。 比如當模組的介面是某個類的執行個體時,需要通過 module.exports來實現:

define(function(require, exports, module) {  // exports 是 module.exports 的一個引用 console.log(module.exports === exports); // true // 重新給 module.exports 賦值 module.exports = new SomeClass(); // exports 不再等於 module.exports console.log(module.exports === exports); // false});

注意:對 module.exports 的賦值需要同步執行,不能放在回呼函數裡。下面這樣是不行的:

// x.jsdefine(function(require, exports, module) { // 錯誤用法 setTimeout(function() { module.exports = { a: "hello" }; }, 0);});

在 y.js 裡有調用到上面的 x.js:

// y.jsdefine(function(require, exports, module) { var x = require(‘./x‘); // 無法立刻得到模組 x 的屬性 a console.log(x.a); // undefined});
小結

這就是 CMD 模組定義規範的所有內容。經常使用的 API 只有 define, require, require.async, exports,module.exports 這五個。其他 API 有個印象就好,在需要時再來查文檔,不用刻意去記。

與 RequireJS 的 AMD 規範相比,CMD 規範盡量保持簡單,並與 CommonJS 和 Node.js 的 Modules 規範保持了很大的相容性。通過 CMD 規範書寫的模組,可以很容易在 Node.js 中運行,後續會介紹。

 

CMD 模組定義規範

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.