AMD和CMD
AMD和CMD在ES6出了官方标准以后就很少使用了,所以这里只做了就可以
浏览器端模块化的难题
CommonJS的工作原理
当使用require(模块路径)
导入一个模块时,node会做以下两件事情(不考虑模块缓存):
- 通过模块路径找到本机文件,并读取文件内容
- 将文件中的代码放入到一个函数环境中执行,并将执行后module.exports的值作为require函数的返回结果
正是这两个步骤,使得CommonJS在node端可以良好的被支持
可以认为,CommonJS是同步的,必须要等到加载完文件并执行完代码后才能继续向后执行
当浏览器遇到CommonJS
当想要把CommonJS放到浏览器端时,就遇到了一些挑战
- 浏览器要加载JS文件,需要远程从服务器读取,而网络传输的效率远远低于node环境中读取本地文件的效率。由于CommonJS是同步的,这会极大的降低运行性能
- 如果需要读取JS文件内容并把它放入到一个环境中执行,需要浏览器厂商的支持,可是浏览器厂商不愿意提供支持,最大的原因是CommonJS属于社区标准,并非官方标准
新的规范
基于以上两点原因,浏览器无法支持模块化
可这并不代表模块化不能在浏览器中实现
要在浏览器中实现模块化,只要能解决上面的两个问题就行了
解决办法其实很简单:
- 远程加载JS浪费了时间?做成异步即可,加载完成后调用一个回调就行了
- 模块中的代码需要放置到函数中执行?编写模块时,直接放函数中就行了
基于这种简单有效的思路,出现了AMD和CMD规范,有效的解决了浏览器模块化的问题。
AMD
全称是Asynchronous Module Definition,即异步模块加载机制
require.js实现了AMD规范
在AMD中,导入和导出模块的代码,都必须放置在define函数中
// src引入require.js;通过data-main 确定模块化的入口文件
<script data-main="./js/index.js" src="./js/require.js"></script>
define([依赖的模块列表], function(模块名称列表){ // 位置一一对应
*//模块内部的代码*
*return* 导出的内容
})
// 或者
define((require,exports,module) => {
const a = require('a') // 导入
module.exports = { // 导出
}
})
CMD
全称是Common Module Definition,公共模块定义规范
sea.js实现了CMD规范
在CMD中,导入和导出模块的代码,都必须放置在define函数中
<script src="./js/sea.js"></script> // 引入sea.js
<script> // 确认入口文件
seajs.use("./js/index")
</script>
define(function(require, exports, module){
*//模块内部的代码*
})
// CMD支持异步写法
define((require, exports, module) => {
require.async("a", function(a){
console.log(a)
})
require.async("b", function(b){
console.log(b)
})
})
从使用时看AMD和CMD基本类似,AMD也支持CMD的写法,为什么还有个CMD呢?其实最开始的时候AMD只有一种写法,后面出来了CMD以后,开发者更喜欢CMD的写法,因为与commonjs写法比较类似,AMD再去更新了CMD的写法
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 chenMing!