JavaScript中常说的模块规范
- CommonJS 规范
- AMD 规范
- UMD 规范
- ES6 模块 规范
CommonJS 规范
CommonJS 规范定义了模块应该怎样进行编写,从而各个模块系统之间可以进行相互操作。
var beta = require('beta');
function verb {
return beta.verb();
}
module.exports = {
verb: verb
};
CommonJS 有以下特点:
- 一个文件就是一个模块;
- 使用require()载入模块,使用module.exports输出模块,因此各个模块间可以进行交互;
- 不支持异步加载
AMD 规范
顾名思义,异步模块定义(AMD)主要为了解决异步加载模块而提出,它通过指定模块和依赖项的方式来定义模块。
define("alpha", ["require", "exports", "beta"], function (
require,
exports,
beta
) {
exports.verb = function () {
return beta.verb();
// 或者可以这么写
return require("beta").verb();
};
});
在该示例中,导出 ID 为 alpha 的模块,依赖了 ID 为 beta 的模块。
现在我们知道,Node.js 环境中的模块系统基于 CommonJS 规范,而浏览器环境中需要使用 AMD 实现。
那么如果我们有一个模块,需要同时能运行在 Node.js 环境和浏览器环境中,要怎么办?我们可以使用 UMD 模式。
UMD 规范
为了兼容 AMD 和 CommonJS 的规范,通用模块定义(UMD)模式被提出,它在兼容两者的同时,也支持了传统的全局变量模式。
(function (root, factory) {
if (typeof define === "function" && define.amd) {
// AMD
define(["jquery"], factory);
} else if (typeof exports === "object") {
// CommonJS
module.exports = factory(require("jquery"));
} else {
// 全局变量
root.returnExports = factory(root.jQuery);
}
})(this, function ($) {
// ...
});
UMD 模块头部通常都会有用来判断模块加载器环境的代码,并根据不同的环境提供了不同的方式进行加载。
ES6 模块 规范
// import 导入
import BaseTask, { TaskType } from "./BaseTask";
// export 导出
export { BaseTask };
在该示例中,使用import加载模块,使用export输出模块。
ES6 模块的特点如下:
- 使用import加载和export输出;
- 一个模块只会加载一次(CommonJS 也是一样);
- 导出的模块为变量引用,因此可以在内存中共享。
现在大多数前端项目中都使用 ES6 模块,由于 ES6 模块化目的是编译阶段确定模块间依赖关系,因此我们需要在编译的时候使用 Babel、Webpack 等方式构建依赖关系树。
除此之外,ES6 模块化在各个浏览器里的兼容性差异较大,因此同样需要进行 Babal 编译以及 Webpack 进行打包,这个过程我们称之为 前端代码构建.