查看dojo源碼過程中,發現這三個模塊名並不以dojo、dijit、dojox開頭,在dojo加載器中屬於特殊模塊名。
require
這是一個上下文智能的加載器。
我們通過dojoConfig配置了一個package:myApp,現在對myApp目錄下的文件可以使用如下方式請求:
// this is "myApp/topLevelHandlers"
define(["dojo"], function(dojo){
dojo.connect(dojo.byId("debugButton"), "click", function(){
require(["myApp/perspectives/debug"], function(perspective){
perspective.open();
});
});
});
通過全局的require函數請求一個myApp包下的文件仍然用“包名+文件路徑”的形式。如果我們希望像define那樣使用相對路徑加載模塊:reqiure(['./perspectives/debug'], function(){debug});而require是無法找到“./perspectives/debug”這個module的。這時就輪到這個上下文智能的require模塊上場了。
// this is "myApp/topLevelHandlers"
define(["dojo", "require"], function(dojo, require){
dojo.connect(dojo.byId("debugButton"), "click", function(){
require(["./perspectives/debug"], function(perspective){
perspective.open();
});
});
});
通過引用reqire模塊代替全局require函數,我們可以使用相對路徑來加載模塊,這就是上下文智能。
exports
exports這個模塊的作用與node.js中exports的作用類似,用於導出當前模塊的方法或者變量。在node中它是唯一導出的出口,但是在dojo中我們可以直接在模塊中返回一個對象字面量。
define([], function(){
return {
someProperty:"hello",
someOtherProperty:"world"
};
});
define(["exports"], function(exports){
exports.someProperty = "hello";
exports.someOtherProperty = "world";
});
一般情況下,這兩種寫法都相同,但是在發生循環依賴情況下,使用exports dojo的加載器可以判斷出模塊是否加載完畢,而不是出於死鎖狀態。
module
- id:一個唯一的模塊id,在程序中唯一標識一個模塊;require([module.id], function(m){}); m代表了該id所對應的模塊;這個屬性在一些需要需要根據模塊id與一個計數器拼接起來的功能時常用到,比如dojo/request/script中callback參數
- uri:代表該模塊的絕對url路徑
- exports:該屬性同上文exports模塊作用類似。稍有區別就是我們可以通過該屬性讓exports指向一個新的對象(通常是一個函數)。類似node中改變模塊中exports引用。
define(“myModule”,["module"], function(module){
module.exports = dojo.declare(/*...*/);
});
原來的exports屬性是一個對象,現在是一個類。下次引用該模塊時就可以用來實例化對象。
define(["myModule"], function(MyModule){
var m = new MyModule();
});
這三個特殊的module是dojo用來兼容其他CommonJs類庫時使用。比如將dojo集成進node,這是另一篇文章要將的。