上一篇介绍了模块化的历史进程以及各个模块化规范的优缺点。而这一篇,主要从模块化规范的实现原理出发,让大家能够更加了解其底层实现,从而应用起来更加得心应手。了解其原理还是有一定必要的,除了能更好的掌握外,更重要的是锻炼自己的思维能力。下面就简单介绍一下模块化规范的原理。
![聊一聊模块化(一)简介篇]()
CommonJS
对于 CommonJS 规范,最重要的就是 require 方法,我们需要带着几个问题去了解 require 的原理实现:
- 当我们引入一个模块的时候,我们究竟做了怎样一件事情?
- exports 和 module.exports 有什么联系和区别?
在文档中,有简易版的 require 的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function require(/* ... */) { const module = { exports: {} }; ((module, exports) => { function someFunc() {} exports = someFunc; module.exports = someFunc; })(module, module.exports); return module.exports; }
|
(1)require 相当于把被引用的 module 拷贝了一份到当前 module 中
(2)export 实际上是 module.exports 的引用
作为一个引用,如果我们修改它的值,实际上修改的是它对应的引用对象的值。但是如果我们修改其引用地址,对于其原来的内容并不会有影响,反而切断了与 module.exports 的联系。
1 2 3 4 5 6 7 8 9 10 11
| exports.a = 1
module.exports = { a: 1 }
exports = {a: 1}
let other = {a: 1} exports = other
|
AMD
AMD 规范中的核心就是 define 和 require 方法,下面来看看这两个方法的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| (function(global){ var modules = {}; var define = function (id,factory) { if(!modules[id]){ modules[id] = { id : id, factory : factory }; } }; var require = function (id) { var module = modules[id]; if(!module){ return; }
if(!module.exports){ module.exports = {}; module.factory.call(module.exports,require,module.exports,module); }
return module.exports; }
global.define = define; global.require = require; })(this);
|
参考
- Javascript 模块化管理的来世今生
- 从 IIFE 聊到 Babel 带你深入了解前端模块化发展体系