這里是seajs loader的核心部分,有些IE兼容的部分還不是很明白,主要是理解各個模塊如何依賴有序加載,以及CMD規范。
代碼有點長,需要耐心看:
代碼如下:
/**
* The core of loader
*/
;(function(seajs, util, config) {
// 模塊緩存
var cachedModules = {}
// 接口修改緩存
var cachedModifiers = {}
// 編譯隊列
var compileStack = []
// 模塊狀態
var STATUS = {
'FETCHING': 1, // The module file is fetching now. 模塊正在下載中
'FETCHED': 2, // The module file has been fetched. 模塊已下載
'SAVED': 3, // The module info has been saved. 模塊信息已保存
'READY': 4, // All dependencies and self are ready to compile. 模塊的依賴項都已下載,等待編譯
'COMPILING': 5, // The module is in compiling now. 模塊正在編譯中
'COMPILED': 6 // The module is compiled and module.exports is available. 模塊已編譯
}
function Module(uri, status) {
this.uri = uri
this.status = status || 0
// this.id is set when saving
// this.dependencies is set when saving
// this.factory is set when saving
// this.exports is set when compiling
// this.parent is set when compiling
// this.require is set when compiling
}
Module.prototype._use = function(ids, callback) {
//轉換為數組,統一操作
util.isString(ids) && (ids = [ids])
// 使用模塊系統內部的路徑解析機制來解析并返回模塊路徑
var uris = resolve(ids, this.uri)
this._load(uris, function() {
// Loads preload files introduced in modules before compiling.
// 在編譯之前,再次調用preload預加載模塊
// 因為在代碼執行期間,隨時可以調用seajs.config配置預加載模塊
preload(function() {
// 編譯每個模塊,并將各個模塊的exports作為參數傳遞給回調函數
var args = util.map(uris, function(uri) {
return uri ? cachedModules[uri]._compile() : null
})
if (callback) {
// null使回調函數中this指針為window
callback.apply(null, args)
}
})
})
}
// 主模塊加載依賴模塊(稱之為子模塊),并執行回調函數
Module.prototype._load = function(uris, callback) {
// 過濾uris數組
// 情況一:緩存中不存在該模塊,返回其uri
// 情況二:緩存中存在該模塊,但是其status < STATUS.READY(即還沒準備好編譯)
var unLoadedUris = util.filter(uris, function(uri) {
return uri && (!cachedModules[uri] ||
cachedModules[uri].status < STATUS.READY)
})
var length = unLoadedUris.length
// 如果length為0,表示依賴項為0或者都已下載完成,那么執行回調編譯操作
if (length === 0) {
callback()
return
}
var remain = length
for (var i = 0; i < length; i++) {
// 閉包,為onFetched函數提供上下文環境
(function(uri) {
// 創建模塊對象
新聞熱點
疑難解答
圖片精選