模块系统
CommonJS、ESM、rest/spread。
30 分钟
模块系统
javascript-core 介绍 ESM 基础;本课对比 CommonJS(CJS) 与 ES Module(ESM),并深入 rest/spread 在模块边界的数据传递。Node 双模块见 nodejs-essentials;前端打包见 react-essentials。
学习目标
- 区分 CJS
require与 ESMimport的加载时机 - 理解 default export 与 named export 的互操作
- 熟练使用 rest/spread 合并配置与参数
ESM(浏览器与现代 Node)
// math.js
export function add(a, b) {
return a + b;
}
export default function multiply(a, b) {
return a * b;
}
// app.js
import multiply, { add } from './math.js';
import * as math from './math.js';
ESM 静态分析:import 必须在顶层;支持 tree-shaking 删除未用导出。
CommonJS(Node 传统)
// logger.js
function log(msg) {
console.log(msg);
}
module.exports = { log };
// 或 module.exports.log = log;
// app.js
const { log } = require('./logger');
CJS 运行时加载:require 可放在条件分支;导出的是值的拷贝(基本类型)或引用(对象)。
CJS 与 ESM 互操作
// ESM 引 CJS:default 常为 module.exports 整体
import pkg from 'legacy-cjs-package';
// CJS 引 ESM:需动态 import
async function load() {
const { add } = await import('./math.js');
}
Node "type": "module" 或 .mjs 扩展名启用 ESM;混用需查阅 package.json 的 exports 字段。
rest / spread
const defaults = { page: 1, size: 20 };
const query = { ...defaults, page: 2, filter: 'js' };
// { page: 2, size: 20, filter: 'js' }
function createLesson(title, ...tags) {
return { title, tags };
}
createLesson('模块', 'esm', 'cjs');
const { page, ...rest } = query;
展开是浅拷贝;嵌套对象需手动深拷贝或 structuredClone。
循环依赖
// a.js
import { b } from './b.js';
export const a = 'A' + b;
// b.js
import { a } from './a.js';
export const b = 'B';
ESM 通过 live binding 处理部分循环;设计上应避免相互 import,提取公共模块。
与构建工具
Vite / webpack 将 ESM 打包;import.meta.url 在 Node 中解析当前模块路径: