RequireJS 是模块管理工具、依赖管理工具、功能和sea.js工具类似。
RequireJS工具的执行机制:
// 使用事件机制defined机制,解耦加载流程
->“模块1”检查依赖,如依赖“模块2”
->创建“模块2”对象,并给“模块2”绑定“defined事件”
->调用“模块2”的init方法,如果“模块2”的js文件未加载,就加载“模块1”的依赖“模块2”的JS文件
->加载“模块2”的JS文件,执行“模块2”中的define方法,接着调用页面加载完成的“load回调函数”
->“load回调函数”取得“模块2”,并调用“模块2”的init方法(再次执行本方法)
->在init方法中检查到“模块2”加载完成,接着执行“模块2”的factory方法,接着触发“defined事件”
->“defined事件”处理器,调用一下“模块1”的check方法
->“模块1”检查依赖加载全部完成,接着执行“模块1”的factory方法
建议
require是异步调用,是加载完成依赖,再调用回调
require放在define方法中的时候,并不能保证模块“exports的方法”是有效的
在define中要“exports方法”的时候,不要使用require去引用依赖,而是在模块前直接声明依赖
以下是代码片段
var requirejs, require, define; // 声明全局变量
(function (global) {
var req, s,contexts = {},
op = Object.prototype,
ostring = op.toString,
hasOwn = op.hasOwnProperty,
defContextName = '_',
cfg = {}; //...
function hasProp(obj, prop) {
return hasOwn.call(obj, prop);
}
function getOwn(obj, prop) {
return hasProp(obj, prop) && obj[prop];
}
if (typeof requirejs !== 'undefined') {
if (isFunction(requirejs)) {
return;
}
cfg = requirejs;
requirejs = undefined;
}
if (typeof require !== 'undefined' && !isFunction(require)) {
//assume it is a config object.
cfg = require;
require = undefined;
}
function newContext(contextName) { // 创建上下文
var Module, context, handlers,
config = {
},
registry = {}, // 模注册表
enabledRegistry = {}, // 可直接使用的模块
defQueue = [];
function normalize(name, baseName, applyMap) { // 标准化地址
}
function getModule(depMap) { // 取得模块
}
handlers = {
'require': function (mod) {
},
'exports': function (mod) {
},
'module': function (mod) {
}
};
Module = function (map) {
};
Module.prototype = {
init: function (depMaps, factory, errback, options) {
},
// ....
fetch: function () { // 加载js文件
},
load: function () { // 加载js文件
},
check: function () { // 检查是否加载js文件,如果没加载就加载,已经加载,就执行工厂方法
},
// ...
on: function (name, cb) {
},
emit: function (name, evt) {
}
};
context = {
config: config,
contextName: contextName,
registry: registry,
defined: defined,
urlFetched: urlFetched,
defQueue: defQueue, // 默认队列
Module: Module,
makeModuleMap: makeModuleMap,
nextTick: req.nextTick,
onError: onError,
//...
configure: function (cfg) {
},
makeRequire: function (relMap, options) {
}
completeLoad: function (moduleName) { // JS 完成加载回调
}
//...
nameToUrl: function (moduleName, ext, skipExt) {
},
load: function (id, url) { // 加载JS资源,创建<script>节点,添加到<head>
},
onScriptLoad: function (evt) { // js文件加载后回调
}
};
// context.require(deps, callback, errback){} = context.makeRequire() = function localRequire(deps, callback, errback){}
context.require = context.makeRequire();
return context;
}
req = requirejs = function (deps, callback, errback, optional) { // 放到全局变量中
var context, config,
contextName = defContextName;
};
req.config = function (config) {
return req(config);
};
if (!require) {
require = req; // 放到全局变量中
}
req.version = version;
//...
req.isBrowser = isBrowser;
s = req.s = {
contexts: contexts,
newContext: newContext
};
req({});
// ...
req.createNode = function (config, moduleName, url) { // 创建<script>对象
};
req.load = function (context, moduleName, url) { // 创建<script>节点,添加到<head>
};
if (isBrowser && !cfg.skipDataMain) {
}
define = function (name, deps, callback) { // 放到全局变量中
};
define.amd = {
jQuery: true
};
req.exec = function (text) {
};
req(cfg);
}(this));