同步加载
- 先使用require.register注册文件路径和对应方法之间的映射关系保存在require.modules中
- 再使用require方法,通过传入的路径去require.modules中取出对应的方法
- 使用require获取方法的同时,会触发依赖模块中的require方法,这样就实现了模块的加载
index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><!-- <script src="./commonJS_async.js"></script> --><script src="./commonJS.js"></script><script src="./modules/hello.js"></script><script src="./modules/name.js"></script><script>var hello = require("hello.js");console.log(hello);console.log(require.modules);// require.ensure('./modules/ajax.js', function (obj) {// console.log(obj);// })</script>
</body>
</html>
复制代码
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, // 模块Idstatus: 'loaded',onload: null,method: fn};}
}require.ensure = function (path, cb) {require.modules[path] = {moduleName: path, // 模块Idstatus: '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 );
}
复制代码