Hardhat测试遇ERR_REQUIRE_ESM错误:require无法加载ES模块Chai
我正在学习Solidity,使用Hardhat执行命令npx hardhat test时出现测试错误,错误信息如下:
error Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Users\user\Desktop\hardtproject\node_modules\chai\chai.js from C:\Users\user\Desktop\hardtproject\test\sample-test.js not supported.
Instead change the require of chai.js in C:\Users\user\Desktop\hardtproject\test\sample-test.js to a dynamic import() which is available in all CommonJS modules.
at Object.(C:\Users\user\Desktop\hardtproject\test\sample-test.js:2:20) {
code: 'ERR_REQUIRE_ESM'
}
我使用的是Node.js 20版本,原本以为该版本支持require关键字,尝试在package.json中添加type: module但未解决问题。我的测试代码如下:
const { assert } = require("chai"); // the `describe` scope encapsulates an entire test called `TestModifyVariable` // the `it` says the behavior that should be expected from the test describe("TestModifyVar", function () { it("should change x to 74", async function () { // this line creates an ethers ContractFactory abstraction const ModifyVar = await ethers.getContractFactory("ModifyVar"); // we then use the ContractFactory object to deploy an instance of the contract const contract = await ModifyVar.deploy(500); // wait for contract to be deployed and validated! await contract.deployed(); // modify x via this function! await contract.setVar(); // getter for state variable x const newX = await contract.variable(); assert.equal(newX.toNumber(), 74); }); });
这里提供三种可行的解决思路:
方案1:安装兼容CommonJS的Chai版本
最新版Chai已切换为ESM-only模块,无法通过require()导入。可以回退到支持双模块格式的4.x版本:npm install chai@4.x --save-dev安装完成后,原有测试代码的
require语句无需修改,直接即可正常运行。方案2:将测试代码改为ESM语法
若想保留最新版Chai,需调整代码和配置适配ESM:- 将测试文件中的
const { assert } = require("chai");替换为ESM导入:import { assert } from "chai"; - 确保项目根目录的
package.json中存在"type": "module"字段;同时将hardhat.config.js改为ESM格式,比如把module.exports = {}替换为export default {}。
- 将测试文件中的
方案3:使用Hardhat内置的断言工具
Hardhat默认集成了Chai的断言功能,无需手动导入Chai。直接删除测试代码中的Chai导入语句,原有assert调用依然可以正常工作:// 移除这一行:const { assert } = require("chai"); describe("TestModifyVar", function () { it("should change x to 74", async function () { // 原有测试逻辑保持不变 assert.equal(newX.toNumber(), 74); }); });
内容的提问来源于stack exchange,提问作者Emma Tungsten

