1. ES6 Modules(原生 JavaScript 模块)
JavaScript 引入了原生模块,可以直接使用 import 和 export 关键字来实现模块化,支持异步/同步导入。
**导出**:可以是默认导出或命名导出。
// math.js
export const add = (a, b) => a + b;
export function subtract(a, b) { return a - b; }
**导入**:
// main.js
import { add, subtract } from './math.js';
console.log(add(2, 3)); // 输出: 5
2. CommonJS
主要用于 Node.js 环境中,采用同步方式加载模块。
**导出**:
// math.js
const add = (a, b) => a + b;
module.exports = { add };
**导入**:
const math = require('./math');
math.add(2, 3)
const { add } = require('./math');
add(2, 3)
commonjs 和 es module 的相同点和不同点
-
相同
- 都支持模块化,每个模块拥有自己的作用域,避免大量变量和函数直接挂在全局对象
- 都支持定义模块的接口(导出)和依赖(导入),实现代码的封装和复用。
-
不同
- 设计初衷与主要环境
es module主要在浏览器环境commonjs主要在 nodejs 环境
- 语法
es moduleimport / export 来实现导入/导出commonjsrequire / module.exports 来实现导入/导出
- 加载机制
es module编译时加载/静态加载,ES2020引入import(modulefier)用于动态导入commonjs运行时加载,模块在运行时动态加载,支持动态导入
- 加载方式
es module异步加载,如:<script type="module">commonjs同步加载,在浏览器端会堵塞渲染
- 设计初衷与主要环境
-
总结
- CommonJS 是一个事实标准,诞生于 Node.js 早期,采用同步、运行时加载,语法基于函数调用 (
require),适合服务器环境。 - ES6 Modules 是 JavaScript 的官方标准,采用静态、编译时加载,语法是语言级别的声明 (
import/export),设计上更适合浏览器和现代开发(支持静态分析、Tree Shaking 等优化),现在已成为主流。
- CommonJS 是一个事实标准,诞生于 Node.js 早期,采用同步、运行时加载,语法基于函数调用 (
3. AMD (理解即可,用的少)
AMD 是一种用于浏览器环境中的异步加载模块的规范,RequireJS 是其最著名的实现之一。
- 特点:
- 异步加载模块。
- 使用
define()定义模块。 - 使用
require()加载模块。
**导出**:
// math.js
define(function() {
return {
add: function(a, b) { return a + b; }
};
});
**导入**:
require(['math'], function(math) {
console.log(math.add(2, 3)); // 输出: 5
});
4. CMD
AMD 是一种类似于 AMD 的模块化规范,但它更倾向于在定义时延迟执行依赖
// math.js
**导出**:
define(function(require, exports, module) {
function add(a, b) {
return a + b;
}
exports.add = add;
});
**导入**:
define(function(require) {
var math = require('./math');
console.log(math.add(2, 3)); // 输出: 5
});
5. UMD (Universal Module Definition)
UMD 是一种旨在兼容多种模块系统的模式,既可以在浏览器环境中以全局变量的形式暴露模块,也可以在支持 CommonJS 或 AMD 的环境中作为模块使用。
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['exports'], factory);
} else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
// Node, CommonJS-like
factory(exports);
} else {
// 浏览器全局变量
factory(root);
}
}(this, function(exports) {
exports.add = function(a, b) { return a + b; };
}));