1、什么是模块化
模块化是指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程,有多种属性,分别反映其内部特性。把一个项目分成若干模块,每个模块完成一个特定的子功能,所有的模块按某种方法组装起来,成为一个整体,完成整个系统所要求的功能。
2、四个前端模块化规范
CommonJS规范、AMD规范、CMD规范、es6模块化规范。
时间线:
- 2009年CommonJS规范被制定,同年,node.js基于Commonjs规范应运而生。
- 2010年,James Burke开发了RequireJS ,并同时发布了AMD规范。
- 2011年,前端大神开发了SeaJS,并同时发布了CMD规范。
- 2015年,js官方发布了ECMAScript的第六个版本,里面包含了es6模块化规范。
适用场景:
- CommonJS规范中,模块加载是同步的,在服务器端,加载的模块是从本地内存或磁盘中读取的,耗时基本可以忽略,所以CommonJS规范在服务器开发环境node.js中完全适用。而在浏览器端,模块加载要请求资源,由于网络请求存在延迟等问题,如果多个js文件之间存在前后依赖,无法保证js文件可以按照正确的顺序被加载,所以CommonJS规范不适用于浏览器端。
- AMD(Asynchronous Module Definition),意思就是"异步模块定义"。它采⽤异步⽅式加载模块,模块的加载不影响它后⾯语句的运⾏,适用于浏览器端,AMD规范是RequireJS开发过程中对模块定义的规范化产出。
- CMD(Common Module Definition),意思是“通用模块定义”。CMD是SeaJS 在推广过程中对模块定义的规范化产出。和AMD一样适用于浏览器端。
- es6模块化规范,作为官方发布的一个模块化标准,一经推出就受到大量使用,不过目前存在一些浏览器不支持的情况。同时,node.js中也逐渐完善对es6模块化的支持。
总结来说,commonjs使用于后端,比如node.js中,ADM和CMD适用于前端,而es6模块化标准适用于前端、且node.js中也逐渐完善支持它。
3、使用代码演示
因为AMD和CMD已经逐渐不被使用,这里我们只介绍node.js中CommonJS规范的使用,以及es6模块化的使用。
3.1、CommonJS规范
node中,CommonJS规范使用module.exports导出模块,使用require()导入模块。
我们在math.js文件中创建两个方法sum()和sub(),分别实现对a和b相加或相减的功能,然后把这两个方法通过module.exports导出,在index.js中通过require()引入使用。
math.js
//定义了一个基于commonjs规范的模块(commonjs规范认为一个文件就是一个模块)
function sum(a, b) {
return a + b;
}
function sub(a, b) {
return a - b;
}
//使用commonjs规范导出模块
module.exports = {
sum,
sub
}
index.js
//引入math模块
const math = require('./math'); //math.js中的.js可以省略不写
//使用模块内部的方法
const rs1 = math.sum(1, 3);
const rs2 = math.sub(3, 1);
//输出结果
console.log('rs1', rs1);
console.log('rs2', rs2);
执行结果:
3.2、es6规范
使用export导出想要导出的模块,as可以在导出时对模块重命名。
// 单个导出方法
export function sum(a, b) {
return a + b;
}
//多个一起导出
let y = 2;
let x = 1;
export {
x as newX, //导出时重命名
y
}
//默认导出,一个js有且只能有一个默认导出
export default {
name: 'mike'
};
导入:要用 type="module"标识代码中使用了es6模块,使用import导入,注意,导入的模块名要与导出时的模块名一致(default标识的默认导出除外),as 可以对导入的模块进行重命名。
<script type="module">
//单个导入
import { sum, chineseName } from "./math.js";
//整体导入
import * as math from "./math.js";
console.log(sum(1, 2), chineseName)
</script>