ES 模块:JavaScript 模块化的标准方案

ES 模块:JavaScript 模块化的标准方案

什么是 ES 模块?

ES 模块(ES Modules,简称 ESM)是 ECMAScript 2015(ES6)引入的官方模块化规范。

ES 模块 vs CommonJS

特性 CommonJS ES Modules
加载方式 同步 异步
执行时机 运行时 编译时
导出 module.exports export
导入 require() import
顶层 this module.exports undefined

基本用法

导出

javascript 复制代码
// utils.js

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

// 默认导出
export default function greet(name) {
  return `Hello, ${name}!`;
}

导入

javascript 复制代码
// main.js

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

// 导入默认导出
import greet from './utils.js';

// 重命名导入
import { add as sum } from './utils.js';

// 导入所有
import * as utils from './utils.js';

动态导入

javascript 复制代码
// 动态加载模块
async function loadModule() {
  const module = await import('./utils.js');
  console.log(module.add(2, 3));
}

// 条件加载
if (condition) {
  import('./feature.js').then(module => {
    module.init();
  });
}

模块解析

文件扩展名

javascript 复制代码
// 必须包含扩展名
import { func } from './utils.js';

// 不能省略
import { func } from './utils'; // ❌

绝对路径

javascript 复制代码
// 从 node_modules 导入
import React from 'react';

// 绝对路径导入
import { utils } from '/path/to/utils.js';

模块作用域

javascript 复制代码
// 模块顶层变量不会污染全局作用域
const privateVar = 'secret';

// 只有导出的内容才能被外部访问
export const publicVar = 'public';

循环依赖

javascript 复制代码
// a.js
import { b } from './b.js';
export const a = 'a';

// b.js
import { a } from './a.js';
export const b = 'b';

在浏览器中使用

html 复制代码
<script type="module" src="main.js"></script>
javascript 复制代码
// main.js
import { greet } from './utils.js';
console.log(greet('World'));

在 Node.js 中使用

json 复制代码
{
  "type": "module"
}
javascript 复制代码
// package.json 设置后可以使用 ESM
import fs from 'fs';
import path from 'path';

模块打包

Webpack 配置

javascript 复制代码
module.exports = {
  entry: './src/main.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ]
  }
};

Rollup 配置

javascript 复制代码
export default {
  input: 'src/main.js',
  output: {
    file: 'dist/bundle.js',
    format: 'esm'
  }
};

最佳实践

1. 保持导出简洁

javascript 复制代码
// ❌ 不好:导出过多
export const a = 1;
export const b = 2;
export const c = 3;

// ✅ 好:按需导出
export { a, b } from './constants.js';
export { default as c } from './c.js';

2. 使用命名导出

javascript 复制代码
// ✅ 推荐:命名导出便于 tree-shaking
export function util1() {}
export function util2() {}

3. 避免循环依赖

javascript 复制代码
// ❌ 不好:循环依赖
// a.js
import { b } from './b.js';

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

总结

ES 模块为 JavaScript 提供了标准化的模块化方案:

  1. 静态分析:支持 tree-shaking
  2. 异步加载:更好的性能优化
  3. 标准规范:跨平台兼容
  4. 清晰语义:明确的导入导出语法

掌握 ES 模块是现代前端开发的必备技能。

相关推荐
OpenCSG3 分钟前
Hugging Face遭遇AI Agent攻击:AI资产管理正在进入新阶段
人工智能·大模型
JaydenAI3 分钟前
[A2A协议与实现-06]如何将一个MAF Agent发布为A2A服务[JSON-RPC]
ai·agent·sse·a2a·maf
神奇霸王龙4 分钟前
AI视频Prompt结构化实战指南:可灵/万相/豆包
人工智能·ai·prompt·aigc·音视频·ai编程
aax12134538 分钟前
VOC 集群治理工程实操|美丽蓝天绿岛项目 RTO 工艺选型、管控方案与申报要
大数据·数据库·人工智能
Scott9999HH23 分钟前
【工控选型破局】拒绝盲目溢价与低质陷阱:基于 Modbus-RTU 状态诊断与自适应滑动中值滤波的 C++ 实战,兼论“性价比高又好用的仪器仪表厂家”选型之道
人工智能
To_OC28 分钟前
调了一上午 DeepSeek 参数,我终于摸透了 temperature 和 Top K 的真实作用
人工智能·llm·deepseek
IvorySQL38 分钟前
PG 日报|优化缓冲区批量扫描,降低多套接字并发竞争
数据库·人工智能·postgresql·开源·区块链
阳光是sunny39 分钟前
LangGraph实战教程:defer延迟节点——让收尾工作自动排到最后
前端·人工智能·后端
70asunflower1 小时前
别再混淆 CUDA 的三个版本:`nvidia-smi`、`nvcc`、`torch.version.cuda` 一次讲清
人工智能
就是一顿骚操作1 小时前
词嵌入 word2vec:Skip-Gram 与 CBOW 经典解读
人工智能·自然语言处理·word2vec·论文解读