为什么要使用模块化?
无模块化的痛点
模块化带来的好处
- 解决命名冲突
- 提供复用性
- 提高代码可维护性
通常,我们在浏览器中使用 ES6 的模块化支持,在 Node,webpack 中使用 commonjs 的模块化支持。
具体实现方式及特点
AMD
require / defined
适用于浏览器端 异步模块加载
是requirejs 在推广过程中对模块定义的规范化产出
对于依赖的模块提前执行,推崇依赖前置
CMD
与AMD很类似
适用于浏览器端 异步模块加载
是seajs 在推广过程中对模块定义的规范化产出,
对于依赖的模块延迟执行,推崇依赖就近
CommonJs
require / module.exports / exports
适用于服务器端 同步的方式加载模块
模块输出的是一个值的 copy,运行时加载,加载的是一个对象(module.exports 属性),该对象只有在脚本运行完才会生成
ES6 Module
import / export
适用于浏览器和服务器端
模块输出的是一个值的引用,编译时输出接口,ES6模块不是对象,它对外接口只是一种静态定义,在代码静态解析阶段就会生成。
异同点
AMD和CMD
AMD 推崇依赖前置、提前执行,CMD推崇依赖就近、延迟执行。
AMD和CommonJs
CommonJS是服务器端模块的规范,Node.js采用了这个规范。CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数AMD推荐的风格通过返回一个对象做为模块对象,CommonJS的风格通过对module.exports或exports的属性赋值来达到暴露模块对象的目的
ES6 Module与CommonJS
ES6 Module和CommonJS模块的异同点:
CommonJS模块是运行时加载,ES6 模块是编译时输出接口。CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用。即ES6 Module只存只读,不能改变其值,具体点就是指针指向不能变,类似constCommonJS加载的是整个模块,将所有的接口全部加载进来,ES6 Module可以单独加载其中的某个接口;CommonJS中的this指向当前模块,ES6 Module中的this指向undefined;
ES6 Module和CommonJS模块的共同点:
CommonJS和ES6 Module都可以对引入的对象内部属性的值进行改变。
目前浏览器对ES6 Module兼容还不太好,我们平时在webpack中使用的export/import,会经过babel转换为CommonJS规范。
参考链接

