随着前端js代码复杂程度提高,js模块化是一个必然趋势,不仅好维护同时依赖明确,不会污染全局。
1.无模块化:通过script标签引入js,相互罗列,但是被依赖的放在前面,否则就会报错。
缺点:污染全局变量,维护成本高,依赖关系不明显
2.commonJS:该规范主要用在服务端的node中,同步方式加载,它有四个重要的环节:module,export,require,global。实际使用时用module.exports定义当前模块输出的接口(不推荐使用exports),用require加载模块。
优点:解决了依赖,全局变量污染的问题。
缺点:只适合用于服务器端
3.AMD:非同步加载模块,允许指定回调,是RequireJS在推广过程中的模块化产出。定义了三个API:
require([module],callback);define(id,[depends],callback),require.config()
即通过define来定义一个模块,然后使用require来加载一个模块,使用require.config()指定引用路径。在使用require.js
的时候我们必须要提前加载所有的依赖,然后才可以使用,而不是需要时再加载
优点:异步加载模块,并行加载模块
缺点:不能按需加载,开发成本太大
4.CMD:AMD推崇依赖前置,提前执行;CMD推崇依赖就近,按需加载,延迟执行。是SeaJS在推广过程中对模块化定义的产出。
5.ES6:通过import关键字引入模块,通过export关键导出模块。使用export default后,在import的时候不需要加上{},模块名字可以随意起
ES6和CommonJS的区别
es6 {
export : '可以输出多个,输出方式为 {}' ,
export default : ' 只能输出一个 ,可以与export 同时输出,但是不建议这么做',
解析阶段确定对外输出的接口,解析阶段生成接口,
模块不是对象,加载的不是对象,
可以单独加载其中的某个接口(方法),
静态分析,动态引用,输出的是值的引用,值改变,引用也改变,即原来模块中的值改变则该加载的值也改变,
this 指向undefined
}
commonJS {
module.exports = ... : '只能输出一个,且后面的会覆盖上面的' ,
exports. ... : ' 可以输出多个',
运行阶段确定接口,运行时才会加载模块,
模块是对象,加载的是该对象,
加载的是整个模块,即将所有的接口全部加载进来,
输出是值的拷贝,即原来模块中的值改变不会影响已经加载的该值,
this 指向当前模块
}