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 扩展可用于在同一个包中混合类型:

  • "type": "module" 包中,Node.js 可以通过使用 .cjs 扩展名命名它来指示将特定文件解释为 CommonJS(因为 .js.mjs 文件都被视为 "module" 包中的 ES 模块)

  • "type": "commonjs" 包中,Node.js 可以被指示将特定文件解释为 ES 模块,方法是使用 .mjs 扩展名命名它(因为 .js.cjs 文件都被视为 "commonjs" 包中的 CommonJS)。

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).