下面给你一份最完整、最容易理解的 ESModule(ESM)用法解析 + 示例代码,前端开发直接可用。
包括:

✅ 基本用法
✅ 默认导出
✅ 具名导出
✅ 重命名导入
✅ 统一导入
✅ 从 HTML 使用 <script type="module">
✅ 跨文件模块案例

非常适合入门/复习/写文档。


🔥 1. ESModule 基本语法规则

ESModule 主要通过两类关键字:

导出(export)

把变量、函数、对象、类暴露出去。

导入(import)

让另外一个 JS 文件使用这些暴露内容。


📌 2. 最常用的几种导出方式


方式 A:具名导出(Named Export)

utils.js

export const PI = 3.14;

export function add(a, b) {
  return a + b;
}

export class Person {
  constructor(name) {
    this.name = name;
  }
}

引入:main.js

import { PI, add, Person } from './utils.js';

console.log(PI);
console.log(add(2, 3));
console.log(new Person("Tom"));


方式 B:默认导出(Default Export)

一个模块只能有 一个 default。

math.js

export default function (a, b) {
  return a * b;
}

导入:

import multiply from './math.js';

console.log(multiply(2, 5));

⚠️ 注意:
default 导入不需要 {},名字可随便起。


方式 C:具名 + 默认导出混用

lib.js

export default function sayHello() {
  console.log("Hello!");
}

export const version = "1.0.0";

导入:

import hello, { version } from './lib.js';

hello();
console.log(version);


📌 3. 导入时重命名(Alias)

module.js

export const a = 10;
export const b = 20;

导入重命名:

import { a as x, b as y } from './module.js';

console.log(x, y);


📌 4. 导入所有内容(import * as)

api.js

export const url = "https://api.xx.com";
export const token = "abc123";
export function getData() {}

main.js

import * as api from './api.js';

console.log(api.url);
api.getData();


📌 5. 重新导出(re-export)

常用于“统一入口”文件 index.js。

utils/add.js

export function add(a, b) {
  return a + b;
}

utils/sub.js

export function sub(a, b) {
  return a - b;
}

utils/index.js

export * from './add.js';
export * from './sub.js';

main.js

import { add, sub } from './utils/index.js';

console.log(add(1, 2));
console.log(sub(5, 3));


📌 6. HTML 中正确加载 ESModule

index.html

&lt;!DOCTYPE html>
&lt;html>
&lt;head>
  &lt;meta charset="utf-8">
  &lt;title>ESModule 示例&lt;/title>
&lt;/head>
&lt;body>

&lt;script type="module" src="./main.js">&lt;/script>

&lt;/body>
&lt;/html>

特点:

  • 默认是严格模式 strict mode
  • 导入路径必须写扩展名 .js
  • 模块按需加载、自动去重,不会重复执行

📌 7. ESModule 支持异步加载(动态 import)

适合按需加载、路由懒加载。

import('./math.js').then(module => {
  console.log(module.default(5, 6));
});

也可以配合 await

const module = await import('./math.js');


📌 8. 最完整的跨文件模块案例(可直接跑)

math.js

export const add = (a, b) => a + b;
export const sub = (a, b) => a - b;
export default function mul(a, b) {
  return a * b;
}

main.js

import mul, { add, sub } from './math.js';

console.log(add(1, 2));   // 3
console.log(sub(5, 3));   // 2
console.log(mul(4, 6));   // 24

index.html

&lt;script type="module" src="./main.js">&lt;/script>

你需要哪一个?