DrillLab
第 48 / 105 道48 / 105 · #308

什么是 ES6 模块

What are ES6 modules

先自己答,再往下看Answer it yourself first

一句话:语言内置的模块系统 ——export 导出、import 导入, 每个文件一个作用域,在编译期就能确定依赖关系

和 CommonJS(Node 的老方案)的差别—— 这才是考点:

CommonJSES Module
语法require / module.exportsimport / export
时机运行时加载编译期确定依赖
能否动态路径能(require(x)静态 import 不能;要动态用import()(返回 Promise)
导出的是值的拷贝活的绑定(原值变了这边也变)
Tree shaking不行可以(因为静态可分析)
顶层 await不支持支持

「编译期确定依赖」为什么重要?因为打包工具能在不运行代码的情况下 知道谁用了什么, 于是能删掉没用到的导出(tree shaking)、 能做代码分割。这是 ESM 最大的实际价值, 不是语法更好看。

会追问:「具名导出和默认导出怎么选?」—— 默认导出对重命名没有约束 (import 时可以叫任何名字), 不利于搜索和自动补全;具名导出更利于 tree shaking 和重构。 实践上「一个文件一个主体」用 default, 工具函数集合用具名。
「Node 里怎么用 ESM?」——package.json"type": "module", 或者文件名用 .mjs。 这就是 Federation 那门课里 Jest 需要--experimental-vm-modules 的原因。

In one line: the module system built into the language — export to expose, import to pull in, one scope per file, and dependencies are known at compile time.

How it differs from CommonJS, Node’s older scheme — this is the part being tested:

CommonJSES Module
Syntaxrequire / module.exportsimport / export
TimingLoaded at runtimeDependencies resolved at compile time
Dynamic pathsYes (require(x))Not with a static import; for that use import(), which returns a Promise
What gets exportedA copy of the valueA live binding (the original changes, so does this one)
Tree shakingNoYes, because it is statically analysable
Top-level awaitNot supportedSupported

Why does “resolved at compile time” matter? Because a bundler can see who uses what without running the code, so it can drop exports nobody imported (tree shaking) and split code. That is ESM’s real practical value, not prettier syntax.

Follow-up: “Named exports or a default export?” — a default export puts no constraint on the name, since an importer can call it anything, which hurts search and autocomplete; named exports are friendlier to tree shaking and refactoring. In practice: default for “one file, one main thing”, named for a bag of utilities.
“How do you use ESM in Node?” — "type": "module" in package.json, or name the file .mjs. That is why Jest needs --experimental-vm-modules in the Federation course.