# JS 模块机制
# 模块的规范
# CommonJS
node的模块系统就是参照CommonJS实现的,用require()进行模块的加载
var math = require('math')
1
# CommonJS循环依赖
require.js只会执行到相互引用的部分,下面的代码不再过问。
这样做会导致出现not defined错误
可以通过不使用前置加载,在使用的地方require即可
ES6中不会出现循环依赖,因为ES6中声明的只是引用,并没有引入
# AMD
浏览器端不同于服务器端,资源需要进行异步加载,否则会造成浏览器的“假死”,AMD的出现解决了这个问题
AMD: Asynchronous Module Definition
require([module], callback); // module为要加载的模块,callback是加载成功之后的回调函数
1
# AMD框架require.js
<script src="1.js"></script>
<script src="2.js"></script>
1
2
2
加载JS的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长;其次,由于js文件之间存在依赖关系,因此必须严格保证加载顺序(比如上例的1.js要在2.js的前面),依赖性最大的模块一定要放到最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。
require.js的出现解决这两个问题
- 实现js文件的异步加载,避免网页失去响应;
- 管理模块之间的依赖性,便于代码的编写和维护。
#### AMD模块的编写
// 定义模块 math.js,假设依赖mylib
const math = define(['mylib'], function() {
let add = (x, y) => {
return x + y
}
return {
add
}
})
// 调用模块
require(['math'], (math) => {
alert(math.add(1, 1))
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# CMD
来自玉伯的sea.js(Common Module Definition)
# CommonJS 中的 require/exports 和 ES6 中的 import/export 区别
CommonJS 模块的重要特性是加载时执行,即脚本代码在 require 的时候,就会全部执行。一旦出现某个模块被”循环加载”,就只输出已经执行的部分,还未执行的部分不会输出。
ES6 模块是动态引用,如果使用 import 从一个模块加载变量,那些变量不会被缓存,而是成为一个指向被加载模块的引用
import/export 最终都是编译为 require/exports 来执行的