为何在chai的实际使用中却不能在nodejs的代码中进行require引入呢?

我在开源代码中看到有使用require引入chai库的API:

https://github.com/tree-sitter/node-tree-sitter/blob/master/test/tree_test.js#L4

const { assert } = require("chai");

但是我在chai的实际使用中却不能在nodejs的代码中进行require引入:

const { assert } = require("chai");
                   ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/mmkk/Desktop/code/Test/Test-demos/nodejs/nodejs-node-tree-sitter-test-01/node_modules/.pnpm/chai@5.1.1/node_modules/chai/chai.js from /Users/mmkk/Desktop/code/Test/Test-demos/nodejs/nodejs-node-tree-sitter-test-01/test/tree_test.js not supported.

请问这个是什么原因呢?

阅读 1.4k
avatarAI BotBETA

这个错误表明你尝试在一个使用CommonJS模块系统(即require)的Node.js环境中引入了一个ES模块(ESM)。从Chai 5.0开始,Chai提供了两种格式的模块:CommonJS和ESM。然而,如果你遇到了上述错误,很可能是因为Chai包中的某个文件或整个包是以ESM格式发布的,而你的Node.js代码或者项目的package.json文件可能配置为了仅支持CommonJS。

要解决这个问题,你可以采取以下几种方法之一:

  1. 使用动态import()
    如果你的Node.js版本支持(通常是Node.js 12及更高版本),你可以使用动态import()语法来引入ESM模块。例如:

    (async () => {
        const { assert } = await import('chai');
        // ... 使用assert进行断言
    })();

注意:import()返回的是一个Promise,所以你需要使用await来等待模块加载。

  1. 更改你的package.json
    如果你的整个项目都打算使用ESM,你可以在package.json中添加"type": "module",这样Node.js就会将你的.js文件当作ESM来处理。

    {
      "type": "module",
      // ... 其他字段
    }

之后,你就可以直接使用import语法来引入ESM模块,包括Chai。

  1. 安装一个旧的Chai版本
    如果你不想在项目中使用ESM,可以安装一个旧版本的Chai,该版本只提供CommonJS模块。但是请注意,这可能会限制你使用Chai的新功能。
  2. 使用条件引入
    在某些情况下,你可能需要根据运行时环境来动态地选择使用哪种模块格式。这通常涉及到检查process.versions.modules等属性来确定Node.js是否支持ESM,并据此进行条件性的requireimport
  3. 使用第三方工具
    一些构建工具(如Webpack、Rollup等)或模块解析器可以帮助你处理不同格式的模块。

最后,错误消息中提到的/Users/mmkk/Desktop/code/Test/Test-demos/nodejs/nodejs-node-tree-sitter-test-01/node_modules/.pnpm/chai@5.1.1/node_modules/chai/chai.js文件可能是一个特定于你使用的包管理器(例如pnpm)的路径。确保你的包管理器已正确安装和配置,并且你的Node.js版本支持你正在尝试使用的功能。

2 个回答
✓ 已被采纳

在 JS 中引入其它模块有两种方式,一种是 CommonJS Module,需要使用 require 引入;一种是 ES6 Module,需要使用 import 引入。一般来说,使用 require 无法引入 ES6 Module;使用 import 也无法引入 CommonJS Module。你这里使用 require 引入 ES6 Module,所以 NodeJS 报错了。

JS 的第三方库有的会提供两种格式的模块,有的在旧版本提供 CommonJS Module,而在新版本提供 ES6 Module。

要解决你的问题,要么将 require 改为 ES6 的 import 语法,要么引入 CommonJS 格式的模块。

你的代码被认为是 ES Module 了,考虑配置将整个项目设置为 commonjs 或者把文件后缀改成 cjs

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏