ESM 在前端开发中的介绍和使用指导

ESM(ECMAScript Modules)前端开发介绍与使用指南

一、什么是 ESM?

ECMAScript Modules(ESM) 是 JavaScript 语言官方标准化的模块系统,自 ECMAScript 2015(ES6) 起正式引入,并在后续版本中不断完善。作为现代 Web 开发的基石,ESM 解决了长期以来 JavaScript 缺乏原生模块化支持的问题。

模块化历史演进

阶段 方案 特点
早期 全局变量模式 功能挂载到全局对象,易冲突
中期 CommonJS Node.js 使用,同步加载
中期 AMD/UMD 浏览器异步加载,配置复杂
现代 ESM 原生标准,静态分析,树摇优化

二、ESM 核心语法

1. 导出(Export)

复制代码
// 命名导出
export const PI = 3.14159;
export function add(a, b) {
  return a + b;
}

// 默认导出(每个模块只能有一个)
export default function main() {
  console.log('默认导出');
}

// 批量导出
export { PI, add, main };

// 重命名导出
export { PI as MathPI };

2. 导入(Import)

复制代码
// 导入默认导出
import main from './module.js';

// 导入命名导出
import { PI, add } from './module.js';

// 导入全部
import * as utils from './module.js';

// 重命名导入
import { PI as CirclePI } from './module.js';

// 动态导入(按需加载)
const module = await import('./module.js');

3. ES2025 新特性:JSON 模块支持

复制代码
// 无需 fetch + JSON.parse,直接导入
import configData from './config-data.json' with { type: 'json' };

// 静态导入
import packageInfo from './package.json' assert { type: 'json' };

三、前端项目中使用 ESM

1. HTML 中直接使用

复制代码
<!DOCTYPE html>
<html>
<head>
  <title>ESM 示例</title>
</head>
<body>
  <!-- 使用 type="module" -->
  <script type="module" src="./main.js"></script>
  
  <!-- 内联模块 -->
  <script type="module">
    import { add } from './utils.js';
    console.log(add(1, 2));
  </script>
</body>
</html>

2. 构建工具配置

Vite(推荐,原生 ESM 支持)
复制代码
// vite.config.js
export default {
  // Vite 默认使用 ESM,无需额外配置
  optimizeDeps: {
    esbuildOptions: {
      target: 'es2020'
    }
  }
}
Webpack
复制代码
// webpack.config.js
module.exports = {
  experiments: {
    outputModule: true  // 启用 ESM 输出
  },
  output: {
    module: true,
    chunkFormat: 'module'
  }
}
package.json 配置
复制代码
{
  "type": "module",  // 启用 ESM
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    }
  }
}

四、ESM vs CommonJS 对比

特性 ESM CommonJS
语法 import/export require/module.exports
加载方式 静态分析,编译时加载 动态加载,运行时加载
执行时机 模块加载时执行 调用时执行
绑定方式 活绑定(引用) 值拷贝
树摇优化 ✅ 支持 ❌ 不支持
浏览器支持 ✅ 原生支持 ❌ 需转换
异步加载 import() ❌ 需额外处理

五、最佳实践

1. 模块组织

复制代码
src/
├── index.js          # 入口文件
├── components/       # 组件模块
├── utils/           # 工具函数
├── services/        # API 服务
└── styles/          # 样式文件

2. 代码分割与懒加载

复制代码
// 路由级代码分割
const Home = () => import('./pages/Home.vue');
const About = () => import('./pages/About.vue');

// 条件加载
if (condition) {
  const module = await import('./heavy-module.js');
  module.init();
}

3. 避免循环依赖

复制代码
// ❌ 不良实践:循环引用
// a.js
import { b } from './b.js';

// b.js
import { a } from './a.js';

// ✅ 解决方案:提取公共模块
// common.js
export const shared = {};

// a.js & b.js 都从 common.js 导入

4. 纯 ESM 包发布(2025 趋势)

根据 Vue/Vite 核心团队成员 Anthony Fu 的建议,2025 年推荐发布纯 ESM 包

复制代码
{
  "type": "module",
  "exports": {
    ".": "./dist/index.js"
  },
  "engines": {
    "node": ">=18.0.0"
  }
}

六、兼容性处理

1. 浏览器支持

浏览器 最低支持版本
Chrome 61+
Firefox 60+
Safari 10.1+
Edge 16+

2. 降级方案

复制代码
<!-- 模块脚本 -->
<script type="module" src="./app.js"></script>

<!-- 降级脚本(不支持 module 的浏览器) -->
<script nomodule src="./app-legacy.js"></script>

3. Babel 转换配置

复制代码
// babel.config.js
module.exports = {
  presets: [
    ['@babel/preset-env', {
      targets: {
        browsers: ['>0.25%', 'not dead']
      },
      modules: false  // 保留 ESM 语法
    }]
  ]
}

七、ES2025 ESM 新特性

特性 说明 状态
JSON 模块导入 原生支持 .json 文件导入 ✅ 已发布
Import Attributes with { type: 'json' } 语法 ✅ 已发布
延迟模块评估 优化模块加载性能 ✅ 已发布
动态 import() 增强 更好的错误处理 ✅ 已发布
复制代码
// ES2025 JSON 模块示例
import config from './config.json' with { type: 'json' };
console.log(config.apiKey);

// 错误处理
try {
  const module = await import('./optional-module.js');
} catch (error) {
  console.error('模块加载失败:', error);
}

八、常见问题与解决方案

1. CORS 错误

复制代码
// 确保服务器设置正确的 CORS 头
// Access-Control-Allow-Origin: *

2. 路径问题

复制代码
// ✅ 使用完整路径(带扩展名)
import { util } from './utils/util.js';

// ❌ 避免省略扩展名
import { util } from './utils/util';

3. Node.js 中使用 ESM

复制代码
// package.json
{
  "type": "module"
}

// 或使用 .mjs 扩展名
// app.mjs
import fs from 'fs';

九、总结

优势 说明
🎯 标准化 官方规范,跨平台统一
🚀 性能优化 静态分析支持树摇
📦 代码组织 清晰的依赖关系
🔒 安全性 严格模式,作用域隔离
🌐 浏览器原生 无需额外工具即可使用

2026 年建议

  • ✅ 新项目直接使用 ESM
  • ✅ 构建工具优先选择 Vite
  • ✅ 发布 npm 包推荐纯 ESM
  • ⚠️ 老项目逐步迁移,注意兼容性

ESM 已成为现代前端开发的标准配置,掌握 ESM 是前端开发者的必备技能!

相关推荐
禾味1 小时前
过程即奖励|前端转后端经验分享
前端·后端·面试
苡~2 小时前
【openclaw+claude】手机+OpenClaw+Claude实现远程AI编程系列大纲
java·前端·人工智能·智能手机·ai编程·claude api
Ryan今天学习了吗2 小时前
前端知识体系总结-前端工程化(Webpack篇)
前端·面试·前端工程化
Ryan今天学习了吗2 小时前
前端知识体系总结-前端工程化(Babel篇)
前端·面试·前端工程化
GISer_Jing2 小时前
基于 OpenClaw 构建 博客自动撰写 Agent
前端·aigc·ai写作
潜水豆2 小时前
基于cursor 的自用专家系统v0.2
前端
Ryan今天学习了吗2 小时前
前端知识体系总结-前端工程化(Vite篇)
前端·面试·前端工程化
Neon12042 小时前
WKWebView 中 iframe 无法监听原生 JSBridge 回调的完整分析
前端
用户8168694747252 小时前
Chrome 插件开发入门
前端