自从es6模块化出现之后,AMD和CMD就很少被使用了,这节课的知识点了解即可,有兴趣的可以去查阅相关的文档.
浏览器端模块化的难题
CommonJS的工作原理
当使用require导入一个模块时,node会做以下两件事情:
1.通过模块路径找到本机文件,并读取文件内容
2.将文件中的代码放入到一个函数环境中执行,并将执行后module.exports的值作为require函数的返回结果
可以认为,CommonJS是同步的,必须要等到加载完文件并执行完代码后才能继续向后执行
当浏览器遇到CommonJS
当想要把CommonJS放到浏览器端时,就遇到了一些挑战:
1.浏览器要加载js文件,需要远程从服务器读取,而网络传输的效率远远低于node环境中读取本地文件的效率,由于commonjs是同步的,会极大的降低运行性能
2.如果需要读取js文件内容并把它放入到一个环境中执行,需要浏览器厂商的支持,可是浏览器厂商不愿意提供支持,最大的原因是commonjs属于社区标准,并非官方标准
新的规范
基于以上两点原因,浏览器无法支持模块化
可这并不代表模块化不能在浏览器中实现
要在浏览器中实现模块化,只要能解决上面的两个问题就行了
解决办法其实很简单:
1.远程加载js浪费了时间?做成异步即可,加载完成后调用一个回调就i行了
2.模块中的代码需要放置到函数中执行?编写模块时,直接放函数就行了
基于这种简单有效的思路,出现了AMD和CMD,有效的解决了浏览器模块化的问题
AMD规范
全称是Asynchronous Module Definition,即异步模块加载机制
require.js实现了AMD规范
在AMD中,导入和导出模块的代码,都必须放置在define函数中
define([依赖的模块列表],function(模块名称列表){
// 模块内部的代码
return 导出的内容
})
举个栗子,文件的层级关系如下:

其中require.js为amd的核心文件,主要解决复杂的模块依赖问题,可以从我的gitee下载
test.html文件:
module.png
a.js文件
define(['b'],function(b){
return 'a模块的内容'
})
b.js文件
/**
* requirejs提供了一个define函数,用法如下:
* define(123):导出数字123
* define({name:'test'}):导出一个对象
*/
define(function(){
// 模块内部的代码
var a=1;
var b=2;
return {
name:'b模块',
data:'b模块中的数据'
}
})
c.js
define(function(require,exports,module){
// 这种方式是为了让使用commonjs的人更加方便一点,相当于在commonjs外面套了一个define函数,其他都是一样的
const b=require('b');
console.log(b,'b');
module.exports={
name:'c',
data:'c模块内部的数据'
}
})
index.js入口文件
// 导入b模块
// define(数组):数组里面的参数表示要导入的模块名称(不用写后缀)
define(['b','a','c'],function(b,a,c){//这里的参数b表示导入的b模块的内容
// 注意:前面如果导入了多个模块,function的参数也会是多个,并且和导入的文件一一对应
// 模块内部的代码
// 这里的执行顺序是浏览器先加载b文件,加载完成之后再去执行function里面的代码
})
CMD规范
全称是Common Module Definition,公共模块定义规范
sea.js实现了CMD规范
在CMD中,导入和导出模块的代码,都必须放置在define函数中
define(function(require,exports,module){
//模块内部的代码
})
使用AMD的时候各个模块依赖的js文件最终是通过script标签嵌入到了页面的head元素中,当我们查看使用CMD规范的文件时,并没有在head中找到文件引入
举个栗子:demo的目录结构如下:

index.html主要代码:

a.js文件:

b.js文件:

index.js文件:

这就是关于AMD和CMD我们需要了解的内容了,希望对你有帮助
网友评论