为什么在package.json文件中需要加入"type: module"?

139

我升级了节点并构建了现有文件。

但是它没有构建成功,出现了错误。

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:                          │
   │   ~~/nuxt.config.js                                      │
   │   require() of ES modules is not supported.                                            │
   │   require() of ~~/nuxt.config.js from                    │
   │   ~~/config.js is an ES   │
   │   module file as it is a .js file whose nearest parent package.json contains "type":   │
   │   "module" which defines all .js files in that package scope as ES modules.            │
   │   Instead rename nuxt.config.js to end in .cjs, change the requiring code to use       │
   │   import(), or remove "type": "module" from                                            │
   │   ~~/package.json.  

所以我在package.json文件中删除了'type: module'。

删除它是否可以?

7个回答

184

如果在package.json文件中有"type": "module",则源代码应使用import语法。如果没有,则应使用require语法;也就是说,在package.json中添加"type": "module"可以启用ES6模块。更多信息请参见此处


8
@Alex,“type”:“module”是用于ES模块的。我认为你应该删除你的评论。还可以查看https://developer.okta.com/blog/2019/12/04/whats-new-nodejs-2020。 - Gad D Lord
6
我认为Alex想表达的是,在package.json中省略了type字段,其效果与将其设置为CJS相同。(规范中指出:“如果最近的父级package.json缺少type字段或包含type:commonjs,则.js文件将被视为CommonJS格式。如果到达卷根并且找不到package.json,Node.js会使用默认值,即一个没有type字段的package.json。) - jacobq
2
啊,逗号的差别真是大啊!不,“type”: module 是错误的,但是没有 type:module 是正确的哈哈。请 @alex 澄清一下。 - Collin White
需要注意的是:它将适用于所有导出。所以我还不知道如何混合使用CommonJS和ESM。 - Eric Burel
1
在 package.json 文件中添加了 type module 后,我还能使用 require 语法吗? - alfianrehanusa

29

截至2022年中期的更新

如果您正在使用Node.js v16,并且如果可能的话,您应该使用它,因为它是LTS,您只需要像这里https://blog.logrocket.com/es-modules-in-node-today/所解释的那样使用type: module即可。


如果由于某些原因您仍在使用较低版本的Node.js,您可以按照Flavio的博客文章https://flaviocopes.com/how-to-enable-es-modules-nodejs/进行操作。

并执行以下操作:

  • 在您的package.json文件中添加"type": "module"
  • 启动您的应用程序时使用--experimental-modules,例如:node --experimental-modules app.js

或者如果您已经在使用现代版本的Node,则可以执行以下操作之一:

  • 在您的package.json文件中添加"type": "module"
  • 将您的文件重命名为.mjs扩展名,最终结果看起来像这样node app.mjs

5
除非我理解有误,否则在使用Node 14(已测试版本为14.17.3)时,您仍需要在package.json中声明"type": "module"或者使用.mjs文件扩展名。否则,您将从Node获得类似于“警告:要加载ES模块,请在package.json中设置“type”:“module”或使用.mjs扩展名”的错误和“SyntaxError:无法在模块之外使用import语句”的错误。这也适用于Node 16.5.0。 - superEb
@superEb 不好意思,你是对的,type: module 仍然是必需的。我的错:https://blog.logrocket.com/es-modules-in-node-today/ - kissu

3
@AfsharMohebi的回答非常好,覆盖了最有用的要点。
本答案旨在补充CI/CD管道的相关内容,其中一个可能需要利用添加动态type参数来执行使用ES6 JavaScript编写的节点代码。此外,我知道这与OP的问题无关,但是谷歌将我带到了这里,因此希望其他人也会发现这个有用。
特别地,根据node文档,我们可以使用--input-type=module,如果我们没有包括type:modulepackage.json
例如,我使用下面的命令来测试上传成功并可用的npm包:
mkdir test-mypkg && cd test-mypkg 
echo "import { myFunc } from '@myname/myPkg';" > test.js 
npm i @myname/myPkg @babel/core @babel/node && cat test.js | node --input-type=module

注意:为了进行完整的 ES6 转换为 ES5,可能需要包含 babel 依赖项。此外,您应该考虑固定您正在测试的myPkg包的版本!


0
Node文档中:
“type”字段定义了Node.js用于所有具有该package.json文件作为最近父级的.js文件的模块格式。
当最近的父级package.json文件包含顶级字段“type”且其值为“module”时,以.js结尾的文件将作为ES模块加载。
如果最近的父级package.json缺少“type”字段,或包含“type”:“commonjs”,则.js文件将被视为CommonJS。
因此,默认情况下,Node将.js文件视为CommonJS模块(即您可以使用require和module.exports)。
如果要使用ES模块,您应该在package.json中添加“type”:“module”,以便Node将.js文件视为ES模块(即您可以使用import和export)。

0
从 Node.js 版本 v20.10.0 或更高版本开始,package.json 文件中的 "type": "module" 声明不再必要。
相反,使用 --experimental-detect-module 标志来执行您的程序:
node --experimental-detect-module index.js

或者,您可以使用--experimental-default-type="module"标志来实现相同的结果。
node --experimental-default-type="module" index.js

为了避免每次都添加标志,将其包含在“package.json”文件的“scripts”部分中,如下所示:
{
  ...
  "scripts": {
    "start": "node --experimental-detect-module index.js"
  },
  ...
}

现在,你可以使用以下命令来运行你的程序:
npm run start

即使在项目的其他地方没有出现"type": "module",这种方法仍然有效。

0
在 package.json 文件中添加 "type": "module" 键,以在 Node.js 中使用 ES6 模块。

0
当你从const express = require("express")切换到import { Express } from "express";时,你需要在package.json中插入"type": "module"。它基本上用于启用ES6模块的导入/导出语法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接