粉笔 - 错误 [ERR_REQUIRE_ESM]:要求使用ES模块的require()函数

96

嗨,我试图在我的简单应用程序中安装粉笔(chalk),但是遇到了错误:

Error [ERR_REQUIRE_ESM]: require() of ES Module my-file-is-here  and chalk\node_modules\chalk\source\index.js from my-file-is-here not supported.
Instead change the require of index.js in my-file-is-here to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (`my-file-is-here`) {
  code: 'ERR_REQUIRE_ESM'
}
那是我的代码:
const os = require("os")
const chalk = require("chalk")

console.log("app running")

1
我遇到了同样的问题。 - Khanakia
7
在这里最快的解决方案是将chalk软件包降级到4.1.2版本。这样做可以为我解决问题。 - K. Drab
12个回答

146

Chalk 5已经改为了ESM。他们提供了一个链接,以更好地理解这意味着什么:Pure ESM

来自Chalk README:

重要提示:Chalk 5是ESM。如果你想在TypeScript或构建工具中使用Chalk,现在可能需要使用Chalk 4。

截至本回复,Chalk 4的最后一个版本是4.1.2


1
非常感谢。我遇到了一个降级的大问题。如果这是推荐的,那么我想这还算是“可以”的。 - BonisTech
只需将"chalk": "^4",放入你的package.json文件中。注意他们在此期间更新了该包。 - vandijkstef

113

这与您使用的版本有关,我认为您使用的是5.0.0版本。请改用chalk @ 4.1.2

  1. npm uninstall chalk

然后执行以下操作:

  1. npm i chalk@4.1.2

现在您可以运行您的代码了。

const chalk = require('chalk');
console.log(chalk.blue('Hello world!')); 

2
这对我有效。 - Rendy Saputra
3
注意:2.4.1版本太旧了。上面的回答建议使用4.1.2版本更好。 - Zidong

21

使用 chalk^5 替代 4

您可以在 CJS 中使用 chalk^5 的 动态导入(ESM 版本)

const chalk = import("chalk").then(m=>m.default);

// Option 1
async function main(){
  console.log((await chalk).gray(">", ...commands));
}

// Option 2
async function main2(){
  const _chalk = await chalk;
  console.log(_chalk.gray(">", ...commands));
}

降级到v4不是一个长期的解决方案。你应该使用版本v5以准备好ESM。

19

步骤-1 npm uninstall chalk (删除所有chalk文件)


步骤-2 npm install chalk@4.1.0

const chalk = require("chalk");
console.log(chalk.green("Hello World"));

完成


4
一个好的答案总是包含解释,说明为什么这样做可以解决问题,这样发帖人和以后的读者都可以从中学习。 - Tyler2P
1
同意上述观点,但AJ Gray在以下答案中提供了一个很好的解释:https://dev59.com/VVEG5IYBdhLWcg3wN29K#70425265。 - Chrisuu
这些步骤对我解决了问题。顺便说一下。 - Chrisuu

0
在使用esbuild的项目中,当集成最新版本的chalk(v4或v5)时,由于它们使用了ESM和动态导入,可能会遇到问题。为了解决这个问题,您可以在构建过程中引入一个shim,以适当处理动态导入,确保平稳编译。
我已经在这个Gist中记录了完整的过程并提供了有用的资源。然而,为了方便起见,我将在这里概述关键的适应过程。
创建一个构建脚本(例如esbuild-buildscript-with-dynamic-require-shim.mjsbuild.mjs),并包含以下shim,它引入了一个兼容层来处理ESM动态导入:
const ESM_REQUIRE_SHIM = `
await (async () => {
  // ... [omitted for brevity, refer to original post or Gist]
})();
`;

// Configuration for your esbuild
const buildOptions = {
  // ... other options
  banner: { js: ESM_REQUIRE_SHIM }, // Injects the shim as a header in your output files
  bundle: true,
  format: "esm",
  target: "esnext",
  platform: "node",
};

// Execute the build with the options
esbuild.build(buildOptions).catch(() => process.exit(1));

这段代码片段源自esbuild GitHub存储库中讨论的问题解决方案。其中关键的部分是ESM_REQUIRE_SHIM,它作为一个标语/头部注入到每个输出文件中,以协调esbuild对ESM模块的处理与chalk等包的期望之间的差异。
通过在构建配置中包含这个shim,无论您使用的是哪种构建系统或编排器(例如webpack、nx、svelte等),都应该能够解决这个问题。这个Gist还包含了针对各种构建系统的具体指南,例如如何将这个解决方案集成到@nx/esbuild配置中。
作为实际参考,您可以查看我最近在这个esbuild脚本中的实现,同时还有相应的tsconfig.jsonpackage.json以提供额外的上下文。
我欢迎对存储库代码的任何反馈或批评 - 开放的讨论推动改进!
注意:这种方法依赖于esbuild的能力和ESM包的特性。请确保与您项目的依赖和限制兼容。

你在撰写这篇回答时是否使用了任何生成式人工智能? - undefined

0

只需使用版本4而不是5。最新版本已移至ESM。


0
在任何这样的情况下,请使用 import chalk from 'chalk'; // 但在使用之前,您需要对package.json文件进行一些微小的更改, // 将类型更改为模块,例如: "type" : "module"

-1
我只是简单地使用了import chalk from "chalk",并在package.json文件中添加了"type": "module",这使得ES6模块对我非常有效。

1
这种方法可以,但可能会破坏应用程序,并且必须重新编写使用commonjs导入的先前条目。 - Hoàng Huy Khánh

-1
  • 在你的 package.json 中添加 "type": "module"
  • "main": "index.js" 替换为 "exports": "./index.js",并更新你的 package.json
  • 在 package.json 的 "engines" 字段中将 Node.js 版本更新为 12: "node": "^12.20.0 || ^14.13.1 || >=16.0.0"。
  • 从所有 JavaScript 文件中删除 'use strict';
  • 将所有的 require()/module.export 替换为 import/export

对于 imports: import x from '.',只使用完整的相对文件路径:import x from './index.js';

如果你有一个 TypeScript 类型定义(例如 index.d.ts),请更新它以使用 ESM 导入/导出。

可选但建议,使用 node: protocol 进行导入。


1
一个好的答案总是会包括解释为什么这样做可以解决问题,这样原帖作者和任何未来的读者都可以从中学习。 - Tyler2P
请问您能否解释一下为什么应该做这些事情? - Preet Sangha

-1
const chalk = await (await (eval(`import('chalk')`) as Promise<typeof import('chalk')>)).default;

你可以试着用这个。

这个太复杂了。只需要使用(await import('chalk')).default,类型就会自动推断出来。 - undefined
我试过这个,但对我没用。 - undefined

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