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 模块是现代前端开发的必备技能。

相关推荐
SL_staff2 分钟前
规则联动:给工厂装上‘自动化神经反射弧’——JVS·物联网平台规则引擎实战教程
java·人工智能·物联网
众壹新能源科技28 分钟前
逆变器自带无功不够用,加装5MVar SVG后功率因数从0.85回到0.99
运维·人工智能·自动化
king135987455038 分钟前
LFM2.5-24B-A2B Mac 本地部署:内存估算、GGUF/MLX 与 Python 预检脚本
人工智能·macos
sbjdhjd41 分钟前
从签名重放到 Agent Harness:一堂安全课程如何把前端逆向、MCP 与工程约束串起来
网络安全·ai·github·agent·webshell·mcp·harness
DeeGLMath1 小时前
optimtool最新版加速训练分类任务
人工智能·分类·数据挖掘
在所不辞兄1 小时前
为什么神经网络对对抗扰动和分布偏移往往比较脆弱,而人类感知相对更鲁棒?
人工智能·深度学习·神经网络·机器学习
考拉讲支付1 小时前
母婴亲子服务平台分账架构设计:多场景多方分账与合规清结算实践
大数据·运维·人工智能·微信小程序·架构·微信公众平台
xier_ran1 小时前
【infra之路】AI 编译器学习笔记(十三):AI 编译器全景——TVM、XLA、IREE 与其他
人工智能·笔记·学习
用户837133200761 小时前
感觉终于把复杂的 RAG 技术整理明白了
人工智能·llm