模塊不一樣於傳統意義上的腳本文件,由於它定義了一個良好做用域的對象,可以避免污 染全局的命名空間。它可以明確地列出其依賴,和全局對象無關地操做這些依賴,相反的, 接收這些依賴做爲定義模塊函數的參數。RequireJS 中的模塊是模塊模式的一個擴展,具備 不須要參考其餘模塊的全局設置的優點。
對於模塊的 RequireJS 語法容許它們儘量快的被加載,甚至是無序的,可是可以以正 確的依賴順序執行,因爲沒有建立全局變量,因此說在一個頁面中加載多個版本的模塊成爲 了可能。
(若是你熟悉或正在使用 CommonJS 模塊,那麼你也能夠參考下在 CommonJS 註解中的 關於如何將 RequireJS 模塊映射到 CommonJS 模塊中的相關資料)
磁盤上的每一個文件應當只有一個模塊定義。各個模塊能夠經過優化工具劃分爲優化的包。 css
一、簡單鍵值對
若是模塊不依賴於任何模塊,同時只是傳遞一些 name/value 對,那麼只是傳遞了一個 原始的對象給 define():
//Inside file my/shirt.js:
define({ color: "black", size: "unisize" }); 算法
二、定義函數數組
若是模塊不依賴於任何模塊,可是須要使用函數作一些設置工做,那麼定義它本身,傳 遞一個函數給 define():
//my/shirt.js now does setup work //before returning its module definition. define(function () { //Do setup work here
return { color: "black", size: "unisize" } });
瀏覽器
三、定義依賴的函數
app
若是模塊有依賴,那麼第一個參數應該是依賴名稱的數組集合,第二個參數應該是一個 定義的函數。一旦全部依賴都已加載,那麼將調用這個函數來定義模塊。這個函數應該返回 一個定義模塊的對象。這些依賴將做爲參數傳遞給定義的參數,同時按照依賴順序在參數中 列出來。
//my/shirt.js now has some dependencies, a cart and inventory //module in the same directory as shirt.js define(["./cart", "./inventory"], function(cart, inventory) { //return an object to define the "my/shirt" module. return { color: "blue", size: "large", addToCart: function() { inventory.decrement(this); cart.add(this); } } }
);
在上述案例中,my/shirt 模塊已經建立。它依賴於 my/cart 和 my/inventory。磁盤上文 件結構是這樣的:
my/cart.js my/inventory.js my/shirt.js
上述函數調用中指定了兩個參數,’cart’ ’inventory’.這些表明了’./car’ ‘./inventory’模塊。 上述函數直到 my/cart,my/inventory 模塊加載完成後才被調用,它接收模塊做爲 cart 和 inventory 參數 定義全局的模塊是明確不鼓勵使用的,以便一個模塊的多個版本可以在一個頁面上同時 存在(參考高級用法)。同時函數的參數順序應該和依賴的順序相匹配。 函數調用的返回值定義了’my/shirt’模塊。經過這種方式定義模塊, ’my/shirt’並非做爲 一個全局對象而存在的 異步
四、定義一個模塊做爲一個函數 ide
模塊沒有必要必定返回對象。函數中的任何合法返回值都是容許的。下面是一個返回一個函 數做爲它的模塊定義的模塊示例:
//A module definition inside foo/title.js. It uses //my/cart and my/inventory modules from before, //but since foo/bar.js is in a different directory than //the "my" modules, it uses the "my" in the module dependency //name to find them. The "my" part of the name can be mapped //to any directory, but by default, it is assumed to be a //sibling to the "foo" directory. define(["my/cart", "my/inventory"], function(cart, inventory) { //return a function to define "foo/title". //It gets or sets the window title. return function(title) { return title ? (window.title = title) : inventory.storeName + ' ' + cart.name; } } );
函數
五、自定義模塊工具
您可能會遇到的一些 define()函數調用,函數的第一個參數是模塊名稱:
//Explicitly defines the "foo/title" module: define("foo/title", ["my/cart", "my/inventory"], function(cart, inventory) { //Define foo/title object in here. } ); 這些一般是由優化工具生成的。你能夠明確地命名模塊名稱,可是這樣會致使模塊的可 移植性不好。假如你把文件移到另一個目錄,這時你須要修更名稱。最好的實踐是避免編 碼模塊名稱,讓優化工具自行優化模塊名。優化工具須要添加模塊名,以便在一個文件中可 以綁定多個模塊,這樣在瀏覽器中可以加載的更快。
優化
六、其餘模塊說明
一個文件一個模塊: 按照模塊到文件路徑查找算法,每一個 JavaScript 文件應該只定義一個模塊。優化工具會 將多個模塊分組到優化的文件中,可是你只能經過優化工具將多個模塊放到一個文件中。 Define()相對模塊命名: 在 define()函數內部調用 require(‘./relative/name’)以前,確保’require’已經做爲一個依賴, 只有這樣相對名稱才能被正確的解析: define(["require", "./relative/name"], function(require) { var mod = require("./relative/name"); }); 或更好的,對於解析 CommonJS 模塊使用簡潔的語法是可行的。 define(function(require) { var mod = require("./relative/name"); }); 這種形式,將使用 Function.prototype.toStrin()找到 require()調用,並把它們添加依賴 數組中,因爲「require」已加載 ,所以這樣的代碼會正常解析相對路徑。 相對路徑真的很是有用,若是你在一個目錄下建立了一些模塊,那麼你能夠好其餘人或 其餘工程共享這些目錄,同時你可以在那個目錄下的兄弟模塊獲取到一個句柄,而不須要知 道目錄的名稱。 生成相對路徑模塊的 URL 你可能須要生成相對於模塊的 URL。要作到這一點,將’require’做爲依賴,使用 require.toUrl()生成 URL: define(["require"], function(require) { var cssUrl = require.toUrl("./style.css"); }); 控制檯代碼調試 若是你須要在 JavaScript 控制檯和一個已經經過 require(["module/name"], function(){})加 載好的模塊進行調試,那麼你須要使用 require()函數經過模塊名查詢它 require("module/name").callSomeFunction() 注意:這個只有先經過 require 異步加載模塊 require([‘module/name’])纔有效。若是使用的 相對路徑,好比‘./module/name’,這類的只有在 define 內部有效。