js模块规范
简单地介绍下常见的js模块规范,之前跟同事讨论过相关问题,最后总结下来一篇,
常见的模块规范
- CommonJS
- AMD
- CMD
- UMD
- ES6
CommonJS
CommonJS有Mozilla工程师Kevin Dangoor于2009年开始的一个项目,最初叫ServerJS,从最开始的命名我们就可以知道,这个项目的目标是在服务端为js指定模块规范,2009年诞生的nodejs也是参照CommonJS规范实现的。
CommonJS定义的模块分为:
- 模块引用(require)
- 模块定义(exports)
- 模块标识(module)
特点
- 所有代码都运行在模块作用域,不会污染全局作用域。
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 模块加载的顺序,按照其在代码中出现的顺序。
demo1
2
3
4
5
6
7
8
9
10
11
12//module1.js
function test(){
...
}
module.exports = {
test,
}
//example.js
const {test} = require('module1');
test();
AMD
Asynchronous Module Definition (AMD) 诞生的背景是由于commonjs的同步性不适用于浏览器环境,而AMD采用异步方式加载模块,模块的加载不影响后面语句的运行,所有依赖该模块的语句,都定义在一个回调函数中,等到加载完成,该回调函数才执行。
AMD api)1
define(id?, dependencies?, factory);
requirejs和curl.js实现了amd规范
CMD
Common Module Definition 由国内玉伯大神在开发seajs中提出。和amd相近。
cmd和amd的区别
- cmd是延迟执行,amd是提前执行( RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同))
cmd推崇依赖就近(用到的某个模块时再去声明依赖) amd推崇依赖前置(定义模块的时候就声明依赖的模块)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b')
// 依赖可以就近书写
b.doSomething()
// ...
})
// AMD 默认推荐的是
define(['./a', './b'], function(a, b) {
// 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
//...
})
//虽然 AMD 也支持 CMD 的写法,同时还支持将 require 作为依赖项传递,但 RequireJS 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。cmd推崇单一职责模式 amd的api默认是一个多用
UMD
Universal Module Definition
(UMD) 是 amd和commonjs兼容,并支持旧式‘全局’变量定义
ES6
es6(es2015)的模块规范:
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。
export 命令用于规定模块的对外接口。
import 命令用于输入其他模块提供的功能。
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
demo1
2
3
4
5
6
7
8
9
10
11//a.js
function test(){
...
}
export {
test
}
//b.js
import {test} from 'a';
test();