确定模块系统


当作为初始输入传给 node 时,或当 ES 模块代码中的 import 语句引用时,Node.js 会将以下视为ES 模块

  • .mjs 结尾的文件。

  • 当最近的父 package.json 文件包含值为 "module" 的顶层 "type" 字段时,以 .js 结尾的文件。

  • 字符串作为参数传入 --eval,或通过 STDIN 管道传输到 node,带有标志 --input-type=module

Node.js 会将所有其他形式的输入视为 CommonJS,例如 .js 文件,其中最近的父 package.json 文件不包含顶层 "type" 字段,或者没有标志 --input-type 的字符串输入。 此行为是为了保持向后兼容性。 但是,现在 Node.js 同时支持 CommonJS 和 ES 模块,最好尽可能明确。 当作为初始输入传给 node 或被 ES 模块代码中的 import 语句引用时,Node.js 会将以下视为 CommonJS:

  • .cjs 结尾的文件。

  • 当最近的父 package.json 文件包含值为 "commonjs" 的顶层字段 "type" 时,以 .js 结尾的文件。

  • 字符串作为参数传入 --eval--print,或通过 STDIN 管道传输到 node,带有标志 --input-type=commonjs

包作者应该包括 "type" 字段,即使在所有源都是 CommonJS 的包中也是如此。 如果 Node.js 的默认类型发生变化,显式说明包的 type 将使包面向未来,它还将使构建工具和加载器更容易确定应如何解释包中的文件。

Node.js will treat the following as ES modules when passed to node as the initial input, or when referenced by import statements within ES module code:

  • Files ending in .mjs.

  • Files ending in .js when the nearest parent package.json file contains a top-level "type" field with a value of "module".

  • Strings passed in as an argument to --eval, or piped to node via STDIN, with the flag --input-type=module.

Node.js will treat as CommonJS all other forms of input, such as .js files where the nearest parent package.json file contains no top-level "type" field, or string input without the flag --input-type. This behavior is to preserve backward compatibility. However, now that Node.js supports both CommonJS and ES modules, it is best to be explicit whenever possible. Node.js will treat the following as CommonJS when passed to node as the initial input, or when referenced by import statements within ES module code:

  • Files ending in .cjs.

  • Files ending in .js when the nearest parent package.json file contains a top-level field "type" with a value of "commonjs".

  • Strings passed in as an argument to --eval or --print, or piped to node via STDIN, with the flag --input-type=commonjs.

Package authors should include the "type" field, even in packages where all sources are CommonJS. Being explicit about the type of the package will future-proof the package in case the default type of Node.js ever changes, and it will also make things easier for build tools and loaders to determine how the files in the package should be interpreted.