一共有四种模块加载方案
AMD(sea.js),CMD,CommonJS,ES6.
es6的设计思想就是尽量静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。commonJS和AMD都是运行时才能确定这些东西。
ES6可以在编译时就完成模块加载,效率要比CommonJS模块的加载方式高。
模块功能主要由两个命令构成:export和import。export用于规定模块的对外接口,import命令用于输入其他模块提供的功能 一个模块就是一个独立的文件,该文件内部的所有变量,外部无法获取,如果希望外部能够读取模块的某个变量,就必须使用export输出该变量。
1.AMD(require.js),require 的第一个参数表示依赖的模块的路径,第二个参数表示此模块的内容。require.js 会自动分析依赖关系,将需要加载的模块正确加载。
AMD 与 CMD 的区别
1.CMD 推崇依赖就近,AMD 推崇依赖前置
2.对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。看两个项目中的打印顺序:
AMD 和 CMD 都是用于浏览器端的模块规范,而在服务器端比如 node,采用的则是 CommonJS 规范。
CommonJS 规范:导出 module.export 引入require,跟 sea.js 的执行结果一致,也是在 require 的时候才去加载模块文件,加载完再接着执行。
CommonJS 与 AMD:CommonJS 规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。
由于 Node.js 主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以 CommonJS 规范比较适用。
但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用 AMD 规范。
Es6:export import,跟 require.js 的执行结果是一致的,也就是将需要使用的模块先加载完再执行代码。
ES6 与 CommonJS:它们有两个重大差异。
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。
而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
模块加载以后,它的内部变化就影响不到输出的 mod.counter 了。这是因为 mod.counter 是一个原始类型的值,会被缓存,ES6 模块的运行机制与 CommonJS 不一样。
JS 引擎对脚本静态分析的时候,遇到模块加载命令 import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。
换句话说,ES6 的 import 有点像 Unix 系统的“符号连接”,原始值变了,import 加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。