前端模块化
模块化是指将一个复杂的系统分解为多个模块以方便编码。
当项目变得越来越大的时候,原来的引入方式会越来越臃肿,难以维护。
所以在这里需要用模块化的思想来组织代码。目前流行的 前端模块化规范有 CommonJs、AMD、CMD、ES6
CommonJS
CommonJs 是一种被广泛使用的 JavaScript 模块化规范,其核心思想是通过 require 方法来同步加载依赖的其他模块,通过 module.exports 导出需要暴露的接口。它的流行得益于 Node.js 采用了这种方式,后来这种方式就被引入到了 网页开发之中。
1 | let num1 = 0; |
特点
commonJS
用同步的方式加载模块,在服务端
,模块文件都存在本地磁盘,读取很快,但在浏览器端
因为网络等原因,最好的方式应该需要进行异步加载;因为是同步加载,所以只有加载完成,才能执行后面的操作;在服务器端,模块的加载是可以直接运行
的;在浏览器端,模块需要提前编译打包处理
。
机制
CommonJS
模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
1 | // lib.js |
上面的代码说明,lib.js
模块加载完了之后,它的内部变化就影响不到输出的 mod.counter
了。这是因为 mod.counter 是一个原始类型的值,会被缓存。除非写成一个函数
,才能得到内部变动后的值
。
1 | // lib.js |
CMD
CMD 规范专门用于浏览器端,模块的加载是异步的,模块使用时才会加载执行。它整合了 CommonJS 和 AMD 规范的特点最具代表性的是 Sea.js
1 | //定义没有依赖的模块 |
ES6 模块化
ES6 模块化
是国际标准化组织 ECMA 提出的 JavaScript 模块化 规范,它在语言层面上实现了模块化。浏览器厂商和 Node.js 都说要原生支持该规范。他将取代 CommonJs 和 Amd 规范,成为浏览器和服务器通用的模块解决方案。
1 | // 导入 |
缺点
代码无法直接运行在 大部分的 Javascript 运行环境之下,必须通过一些工具转化为浏览器能运行的 ES5
ES6 与 CommonJs 的差异
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
CommonJs 在上文中已经进行分析过,ES6 模块的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令 import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。
CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
因为 CommonJS 加载的是一个对象(即 module.exports 属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
1 | // lib.js |