package.json 和文件扩展名
在包中,package.json
"type"
字段定义了 Node.js 应该如何解释 .js
文件。
如果 package.json
文件没有 "type"
字段,则 .js
文件将被视为 CommonJS。
"module"
的 package.json
"type"
值告诉 Node.js 将该包中的 .js
文件解释为使用 ES 模块语法。
"type"
字段不仅适用于初始入口点 (node my-app.js
),还适用于 import
语句和 import()
表达式引用的文件。
// my-app.js 被当做 ES 模块,
// 因为在同一个文件夹中有 package.json 文件与 "type": "module"。
import './startup/init.js';
// 作为 ES 模块加载,因为 ./startup 不包含 package.json 文件,
// 因此从上一层继承了 "type" 值。
import 'commonjs-package';
// 作为 CommonJS 加载,因为 ./node_modules/commonjs-package/package.json
// 缺少 "type" 字段或包含 "type": "commonjs"。
import './node_modules/commonjs-package/index.js';
// 作为 CommonJS 加载,因为 ./node_modules/commonjs-package/package.json
// 缺少 "type" 字段或包含 "type": "commonjs"。
以 .mjs
结尾的文件总是作为 ES 模块加载,而不管最近的父级 package.json
。
以 .cjs
结尾的文件总是作为 CommonJS 加载,而不管最近的父级 package.json
。
import './legacy-file.cjs';
// 作为 CommonJS 加载,因为 .cjs 总是作为 CommonJS 加载。
import 'commonjs-package/src/index.mjs';
// 作为 ES 模块加载,因为 .mjs 总是作为 ES 模块加载。
.mjs
和 .cjs
扩展可用于在同一个包中混合类型:
Within a package, the package.json
"type"
field defines how
Node.js should interpret .js
files. If a package.json
file does not have a
"type"
field, .js
files are treated as CommonJS.
A package.json
"type"
value of "module"
tells Node.js to interpret .js
files within that package as using ES module syntax.
The "type"
field applies not only to initial entry points (node my-app.js
)
but also to files referenced by import
statements and import()
expressions.
// my-app.js, treated as an ES module because there is a package.json
// file in the same folder with "type": "module".
import './startup/init.js';
// Loaded as ES module since ./startup contains no package.json file,
// and therefore inherits the "type" value from one level up.
import 'commonjs-package';
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
// lacks a "type" field or contains "type": "commonjs".
import './node_modules/commonjs-package/index.js';
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
// lacks a "type" field or contains "type": "commonjs".
Files ending with .mjs
are always loaded as ES modules regardless of
the nearest parent package.json
.
Files ending with .cjs
are always loaded as CommonJS regardless of the
nearest parent package.json
.
import './legacy-file.cjs';
// Loaded as CommonJS since .cjs is always loaded as CommonJS.
import 'commonjs-package/src/index.mjs';
// Loaded as ES module since .mjs is always loaded as ES module.
The .mjs
and .cjs
extensions can be used to mix types within the same
package:
-
Within a
"type": "module"
package, Node.js can be instructed to interpret a particular file as CommonJS by naming it with a.cjs
extension (since both.js
and.mjs
files are treated as ES modules within a"module"
package). -
Within a
"type": "commonjs"
package, Node.js can be instructed to interpret a particular file as an ES module by naming it with an.mjs
extension (since both.js
and.cjs
files are treated as CommonJS within a"commonjs"
package).