Demo代码
随着前端项目的越来越复杂,从代码的编写和维护角度来说,要对项目进行进行模块化开发,在此过程中产生很多模块化规范。
CommonJS
在CommonJS规范中,一个文件就是一个模块,通过module.exports
提供对外的接口,通过require
加载文件模块。
module.exports
是模块的导出接口,个人理解就是在module.exports
对象上挂载变量和函数,在别的模块拿到这个对象。
var x = 5
var addx = function(value) {
return value + x;
}
module.exports.x = x;
module.exports.addx = addx;
使用require
导入模块
var moduleExports = require('./moduleExports.js')
console.log(moduleExports.x)
console.log(moduleExports.addx(5))
对于CommonJS规范,有以下几个注意点
- 每个文件都有单独的作用域,不会污染全局作用域。
- 在模块第一次加载时,会被缓存,如若重新加载模块,就需要清除缓存
- CommonJS加载模块时是同步的,也就是说,只有加载模块完成,才能进行后面的操作。
AMD(Asynchronous Module Definition)
AMD相比较CommonJS,能够异步加载模块,不阻塞程序的进行。require.js
是按照AMD标准模块加载器。AMD标准主要有两步:第一步定义模块,第二部分加载模块。
使用define
定义模块
// 定义模块
/***
* 第一个参数:模块名
* 第二个参数:依赖其他模块
* 第三个参数:从回调函数中导出成员或执行操作
*/
define('module', ['jquery','moduleB'], function($,moduleB){
return{
foo: function() {
$(".div").style.height = 200px;
moduleB()
}
}
})
加载模块
// 载入模块
require(['./module'], function(module){
module.foo()
})
在使用AMD要使用相应的库来配合(在demo 中使用的是require.js库),原生是不支持的。
AMD规范有两点比较烦的地方在于:
- 语法书写比较繁琐
- 若引入模块太多,网络请求就比较繁琐
CMD
CMD是淘宝SeaJS 在推广过程中对模块定义的规范化产出,和AMD规范同一个时期,语法有点类似:AMD和CommonJs的结合。
ES Module
ES Module具体用法参考:ES Module 规范化
ES Module 是ES2015 中的特性,专门为浏览器端模块化提供的规范。
ES Module 最大的特点是:动态只读。
所谓只读:不允许修改引入模块的值,因模块遇到import 时,会生成一个模块引用,当真正用到模块里的成员时,才会去加载。
对于动态:被引用的模块成员发生变化时,其他模块import的值也随之变化。