第4章 模块系统与包管理:CommonJS、ESM、npm/yarn/pnpm面试要点

模块加载与包管理是Node.js架构师面试的必考深水区。面试官通常从机制差异切入,延伸至循环依赖、工程选型、Monorepo治理。本章以"回答框架 + 追问路径"双图驱动,配合3个高频问答与1个真实项目模板,帮你建立从原理到工程的结构化表达。

明确对比范围 CJS vs ESM 核心差异分析 加载 / 绑定 / 作用域 循环依赖处理 部分加载 vs TDZ报错 工程化选型 Node版本 / 项目类型 总结建议 稳定为主 / 渐进迁移 ⬆ 面试回答五步框架:从对比到落地,步步深入

📌 Q1:CommonJS 和 ESM 的核心区别是什么?

🔍 面试官考察点
模块系统理解深度、能否从加载机制 → 绑定方式 → 工程影响系统阐述

📐 回答框架

  • 加载机制:CJS 同步 + 动态 vs ESM 异步 + 静态编译
  • 绑定方式:CJS 值拷贝(浅拷贝) vs ESM 引用映射(只读引用)
  • 作用域:CJS 函数作用域(module wrapper) vs ESM 模块作用域
  • 工程影响:CJS 无法 Tree Shaking;ESM 原生支持,且可做死代码消除

✏️ 示例回答
CommonJS 同步加载、动态解析、值拷贝导出;ESM 异步加载、静态分析、引用映射导出。CJS 运行时确定依赖,ESM 编译时解析,支持 Tree Shaking 和循环依赖编译检测。新项目推荐 ESM,遗留项目通过 .mjs / .cjs 混合使用或转换工具渐进迁移。

⏩ 可能追问

  • ESM 的 import hoisting 是什么?与变量提升有何区别?
  • CJS 的 module.wrapper 函数有什么作用?
  • Node.js 如何同时支持两种模块系统?.mjs / .cjs 的解析规则?