源本科技 | 码上会

ECMAScript 模块化

2026/04/10
1
0

引言

ES6 模块化是 ECMAScript 2015 正式推出的官方标准化模块系统,它终结了前端社区模块化规范混乱的局面。通过 export 导出、import 导入关键字,实现了代码的模块化拆分、复用与解耦。ES6 模块具备静态编译特性,支持 Tree-Shaking 优化,同时兼容浏览器与 Node.js 环境,是现代前端开发的标准规范。

发展历程

在 ES6 模块化诞生之前,JavaScript 作为脚本语言没有原生模块化能力,社区根据不同运行环境推出了多种兼容方案:

历史模块化规范

  • AMD 规范:异步模块定义,专为浏览器设计,代表实现为 RequireJS,支持模块异步加载

  • CMD 规范:通用模块定义,与 AMD 类似,代表实现为 SeaJS,推崇依赖就近、按需加载

  • CommonJS 规范:同步加载模块,专为服务器端设计,Node.js 原生采用的规范,核心语法为 require() 导入、module.exports 导出

这些规范相互独立、语法不兼容,增加了跨环境开发的成本。ES6 模块化的出现,统一了前后端的模块化标准,成为行业通用解决方案。

核心特性

ES6 模块化是语言级别的原生解决方案,同时支持浏览器和 Node.js 环境,核心特性如下:

  • 独立作用域:每个 JS 文件都是一个独立模块,内部变量、函数默认私有,不会污染全局作用域

  • 静态加载:编译阶段就确定模块的依赖关系,支持 Tree-Shaking 剔除无用代码,优化打包体积

  • 统一语法:使用 export 导出模块成员,import 导入模块成员,语法简洁易懂

  • 只读引用:导入的成员是只读引用,无法直接修改,保证模块数据的安全性

Node.js 兼容 ES6 模块

Node.js 最初基于 CommonJS 规范实现模块化,从 v14.15.1 LTS 版本开始正式稳定支持 ES6 模块化,配置方式如下:

环境检查

首先确认 Node.js 版本满足要求:

node -v

项目初始化

执行命令快速生成 package.json 配置文件:

npm init -y

启用 ES6 模块化

package.json 根节点添加配置,声明项目使用 ES 模块:

{
  "type": "module",
  "name": "hello-es6",
  "version": "1.0.0",
  "main": "index.js"
}

注意:添加该配置后,项目中禁止使用 CommonJS 语法require/module.exports),两种规范不能混用。

核心语法

ES6 模块化提供了灵活的导出 / 导入方式,适配不同的开发场景。

默认导出导入

一个模块只能有一个默认导出,适用于模块核心功能导出,导入时可自定义名称。

// moduleA.js 模块
const add = (a, b) => a + b;

// 默认导出
export default add;
// app.js 导入(名称可自定义)
import calculate from './moduleA.js';

console.log(calculate(1, 2)); // 输出:3

按需导出导入

支持导出多个成员,导入时通过解构语法精准获取需要的成员,减少代码冗余。

// moduleB.js 模块
// 多个按需导出
export const add = (a, b) => a + b;
export const sub = (a, b) => a - b;
export const PI = 3.14159;
// app.js 按需导入
import { add, sub } from './moduleB.js';

console.log(add(5, 3)); // 输出:8
console.log(sub(5, 3)); // 输出:2

全部导入与别名

使用 * 导入模块所有成员,配合 as 定义别名,避免命名冲突。

// app.js 全部导入
import * as MathUtils from './moduleB.js';

console.log(MathUtils.PI); // 输出:3.14159
console.log(MathUtils.add(2, 3)); // 输出:5

导入导出别名

为导出 / 导入的成员设置别名,解决命名冲突问题:

// 导出别名
export { PI as MathPI };

// 导入别名
import { PI as MathPI } from './moduleB.js';

混合导出与导入

一个模块可同时使用默认导出 + 按需导出

// moduleC.js
const name = "ES6 Module";
export const version = "ES6";
// 默认导出
export default name;
// 混合导入
import name, { version } from './moduleC.js';

直接导入并执行模块

仅需要执行模块代码,无需导入成员时使用:

// moduleD.js
console.log("模块自动执行");
// 直接导入,无需接收成员
import './moduleD.js';

注意事项

  1. 文件后缀必填 ES6 模块化中,导入本地文件必须书写完整后缀(如 .js),不能省略

  2. 路径必须完整 导入本地模块必须使用相对路径(./../ 开头),不能直接写文件名

  3. 只读限制 导入的成员是只读的,无法修改,避免破坏模块封装性

  4. 单默认导出 一个模块中,export default 只能使用一次

  5. 规范隔离 Node.js 中启用 type: module 后,不能混用 CommonJS 语法

规范对比

规范

运行环境

加载方式

核心语法

CommonJS

Node.js

同步加载

require / module.exports

ES6 模块化

浏览器 + Node.js

静态编译

import / export

总结

  1. ES6 模块化是 JavaScript 官方标准,统一了前后端模块化方案,替代了 AMD、CMD、CommonJS 等历史规范

  2. Node.js 需配置 package.json"type": "module" 才能启用 ES6 模块化

  3. 核心语法分为:默认导出 / 导入、按需导出 / 导入、全部导入、别名使用

  4. 具备独立作用域、静态编译、只读引用等特性,是现代前端工程化的基础