同步加载
先使用require.register注册文件路径和对应方法之间的映射关系保存在require.modules中
再使用require方法,通过传入的路径去require.modules中取出对应的方法
使用require获取方法的同时,会触发依赖模块中的require方法,这样就实现了模块的加载
index.html
Documentvar hello = require("hello.js");
console.log(hello);
console.log(require.modules);
// require.ensure('./modules/ajax.js', function (obj) {
// console.log(obj);
// })
commonJS.js
function require(path) {
let mod = require.modules[path];
mod.exports = {};
mod.call(window, require, mod, mod.exports);
return mod.exports;
}
require.modules = {};
require.register = function (path, fn) {
// 异步加载
require.modules[path] = fn;
}
hello.js、name.js
//hello.js
require.register('hello.js', function (require, module, exports) {
let name = require('name.js')
exports.hello_name = 'hello ' + name;
exports.hello_world = 'hello world';
})
//name.js
require.register('name.js', function (require, module, exports) {
module.exports = 'shimingw'
})
异步加载
异步加载的逻辑匜不复杂,在同步加载的基础上增加require.ensure方法,预先在modules对象上挂在onload方法
修改require.register方法,增加异步模块注册逻辑,在异步模块注册完成后触发onload,以达到模块异步加载的需求
commonJS_async.js
function require(path) {
let mod = require.modules[path].method;
mod.exports = {};
mod.call(window, require, mod, mod.exports);
return mod.exports;
}
require.modules = {};
require.register = function (path, fn) {
// 异步加载
if (require.modules[path] && require.modules[path].status === 'loading') {
// 异步加载成功
require.modules[path].status = 'loaded'
require.modules[path].method = fn;
require.modules[path].onload(require(path));
} else {
require.modules[path] = {
moduleName: path, // 模块Id
status: 'loaded',
onload: null,
method: fn
};
}
}
require.ensure = function (path, cb) {
require.modules[path] = {
moduleName: path, // 模块Id
status: 'loading',
onload: cb,
method: null
};
var head = document.querySelector('head')
var script = document.createElement('script');
script.async = true;
script.src = path;
setTimeout(() => {
head.appendChild(script);
},5000 );
}