介绍
¥Introduction
当传递给 node 作为初始输入时,或者当被 import 语句或 import() 表达式引用时,Node.js 会将以下内容视为 ES 模块:
¥Node.js will treat the following as ES modules when passed to node as the
initial input, or when referenced by import statements or import()
expressions:
-
扩展名为
.mjs的文件。¥Files with an
.mjsextension. -
当最近的父
package.json文件包含值为"module"的顶层"type"字段时,扩展名为.js的文件。¥Files with a
.jsextension when the nearest parentpackage.jsonfile contains a top-level"type"field with a value of"module". -
字符串作为参数传入
--eval,或通过STDIN管道传输到node,带有标志--input-type=module。¥Strings passed in as an argument to
--eval, or piped tonodeviaSTDIN, with the flag--input-type=module. -
代码包含仅成功解析为 ES 模块 的语法,例如
import或export语句或import.meta,没有明确标记应如何解释。显式标记是.mjs或.cjs扩展、带有"module"或"commonjs"值的package.json"type"字段,或者--input-type或--experimental-default-type标志。CommonJS 或 ES 模块均支持动态import()表达式,并且不会强制将文件视为 ES 模块。参见 语法检测。¥Code containing syntax only successfully parsed as ES modules, such as
importorexportstatements orimport.meta, with no explicit marker of how it should be interpreted. Explicit markers are.mjsor.cjsextensions,package.json"type"fields with either"module"or"commonjs"values, or--input-typeor--experimental-default-typeflags. Dynamicimport()expressions are supported in either CommonJS or ES modules and would not force a file to be treated as an ES module. See Syntax detection.
当传递给 node 作为初始输入时,或者当被 import 语句或 import() 表达式引用时,Node.js 会将以下内容视为 CommonJS:
¥Node.js will treat the following as CommonJS when passed to node as the
initial input, or when referenced by import statements or import()
expressions:
-
扩展名为
.cjs的文件。¥Files with a
.cjsextension. -
当最近的父
package.json文件包含值为"commonjs"的顶层字段"type"时,则扩展名为.js的文件。¥Files with a
.jsextension when the nearest parentpackage.jsonfile contains a top-level field"type"with a value of"commonjs". -
字符串作为参数传入
--eval或--print,或通过STDIN管道传输到node,带有标志--input-type=commonjs。¥Strings passed in as an argument to
--evalor--print, or piped tonodeviaSTDIN, with the flag--input-type=commonjs.
除了这些明确的情况之外,还有其他情况,Node.js 根据 --experimental-default-type 标志的值默认使用一个模块系统或另一个模块系统:
¥Aside from these explicit cases, there are other cases where Node.js defaults to
one module system or the other based on the value of the
--experimental-default-type flag:
-
如果同一文件夹或任何父文件夹中不存在
package.json文件,则以.js结尾或没有扩展名的文件。¥Files ending in
.jsor with no extension, if there is nopackage.jsonfile present in the same folder or any parent folder. -
如果最近的父
package.json字段缺少"type"字段,则以.js结尾或没有扩展名的文件;除非该文件夹位于node_modules文件夹内。(当package.json文件缺少"type"字段时,无论--experimental-default-type如何,为了向后兼容,node_modules下的包范围始终被视为 CommonJS。)¥Files ending in
.jsor with no extension, if the nearest parentpackage.jsonfield lacks a"type"field; unless the folder is inside anode_modulesfolder. (Package scopes undernode_modulesare always treated as CommonJS when thepackage.jsonfile lacks a"type"field, regardless of--experimental-default-type, for backward compatibility.) -
当未指定
--input-type时,字符串作为参数传递给--eval或通过STDIN通过管道传递给node。¥Strings passed in as an argument to
--evalor piped tonodeviaSTDIN, when--input-typeis unspecified.
该标志当前默认为 "commonjs",但将来可能会更改为默认为 "module"。因此,最好尽可能明确;特别是,包作者应始终在其 package.json 文件中包含 "type" 字段,即使在所有源都是 CommonJS 的包中也是如此。如果 Node.js 的默认类型发生变化,显式说明包的 type 将使包面向未来,它还将使构建工具和加载器更容易确定应如何解释包中的文件。
¥This flag currently defaults to "commonjs", but it may change in the future to
default to "module". For this reason it is best to be explicit wherever
possible; in particular, package authors should always include the "type"
field in their package.json files, 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.