什么是模块化
通常一个文件是一个模块,有自己的作用域,只对外暴露特定变量和函数
为什么使用模块化
- 代码复用
- 解决依赖关系, 利于维护
- 避免全局变量污染
JS模块化规范有哪些:
- IIFE(早期): 立即执行的匿名函数, 就是一个模块, 匿名函数内部变量不会污染全局对象
- CommonJS
- ES6 Module
- AMD
- CMD
CommonJS
- 主要实践者: Node
- 包含四个环境变量: module exports require global
- CommonJS是同步加载模块
- 适合场景:
- 服务端读取本地磁盘非常快, 所以很适合该规范
- 而浏览器端受限网络, 更适合异步加载
ES6 Module
- 主要由两个命令构成: export import
- 编译时就引入模块代码, 而不是运行时加载
- 无法实现条件加载, 可以实现静态分析
ES6 Module与CommonJS的差异
- CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用。
- CommonJS模块是运行时加载,ES6模块是编译时加载(所以import存在变量提升)
- 运行时加载: CommonJS模块就是对象(即module.exports属性)
- 编译时加载: ES6模块不是对象,而是通过export命令显式指定输出的代码,import时采用静态命令的形式。即在import时可以指定加载某个输出 值,而不是加载整个模块,这种加载称为“编译时加载”
- require支持动态加载, 而import不支持
AMD规范
- 主要实践者: require.js
- require.config()指定引用路径等
- define()定义模块
- require()加载模块
CMD规范
- 主要实践者: sea.js
- define()定义模块
- use()加载模块
require.js和sea.js异同
相同点:requirejs 和 seajs 都是异步加载模块的
不同:
- requirejs 特点是依赖前置,指的是所有依赖提前加载完成
- seajs 特点是就近依赖,指的就是:什么时候用某个模块,那么就什么时候去加载这个模块
但是实际使用中,sea.js也是提前加载完依赖模块, 才执行function,也就跟require.js没什么区别了