Hardhat开发环境迁移:项目升级注意事项
引言:为什么需要升级Hardhat?
你是否还在为Hardhat 2.x版本中的编译速度慢、测试框架老旧而烦恼?Hardhat 3.0带来了革命性的架构升级,基于EDR(Ethereum Development Runtime)重构的核心引擎将编译速度提升40%,全新的Ignition部署系统彻底改变智能合约发布流程,而Node.js测试框架的引入让测试效率翻倍。本文将系统梳理从Hardhat 2.x迁移至3.0的完整路径,帮你避开90%的升级陷阱。
读完本文你将掌握:
- 3步完成项目配置迁移的实操指南
- 插件生态变更后的依赖适配方案
- Ignition部署系统的核心工作流改造
- 测试框架从Mocha迁移至Node.js测试的平滑过渡技巧
- 9个高频迁移问题的解决方案
一、迁移前的兼容性检查
1.1 环境要求变更
Hardhat 3.0对开发环境提出了更严格的要求,在开始迁移前需确保满足以下条件:
| 环境依赖 | 最低版本要求 | 推荐版本 | 检查命令 |
|---|---|---|---|
| Node.js | v20.0.0 | v20.15.1 LTS | node -v |
| npm | v8.0.0 | v10.8.1 | npm -v |
| pnpm | v8.0.0 | v9.6.0 | pnpm -v |
| TypeScript | v5.0.0 | v5.5.4 | tsc -v |
⚠️ 警告:使用非LTS版本的Node.js会触发警告,生产环境建议使用v20.x LTS版本。可通过
nvm install 20 --lts快速安装。
1.2 项目依赖评估
使用以下命令分析当前项目依赖与Hardhat 3.0的兼容性:
# 生成依赖报告
npx depcheck --json > dependency-report.json
重点关注以下包的版本兼容性:
@nomiclabs/hardhat-ethers→ 需迁移至@nomicfoundation/hardhat-ethersv3+@nomiclabs/hardhat-waffle→ 已废弃,替换为@nomicfoundation/hardhat-toolbox-mocha-ethershardhat-deploy→ 与Ignition不兼容,需重构为Ignition模块solidity-coverage→ 需升级至v0.8.12+
二、核心配置文件迁移
2.1 hardhat.config.ts结构变更
Hardhat 3.0引入了类型化配置系统,配置文件结构有重大调整。以下是从v2到v3的迁移示例:
v2配置示例:
import { HardhatUserConfig } from "hardhat/config";
import "@nomiclabs/hardhat-ethers";
import "@nomiclabs/hardhat-waffle";
const config: HardhatUserConfig = {
solidity: "0.8.17",
networks: {
goerli: {
url: `https://goerli.infura.io/v3/${process.env.INFURA_API_KEY}`,
accounts: [`0x${process.env.PRIVATE_KEY}`]
}
}
};
export default config;
v3配置示例:
import type { HardhatUserConfig } from "hardhat/config";
import HardhatViem from "@nomicfoundation/hardhat-viem";
import HardhatIgnitionViem from "@nomicfoundation/hardhat-ignition-viem";
import { configVariable } from "hardhat/config";
const config: HardhatUserConfig = {
solidity: {
profiles: {
default: {
compilers: [{ version: "0.8.22" }],
},
},
},
networks: {
goerli: {
type: "http",
url: "https://goerli.infura.io/v3/" + configVariable("INFURA_API_KEY"),
accounts: [configVariable("PRIVATE_KEY")],
},
edrGoerli: {
type: "edr-simulated",
forking: {
url: "https://goerli.infura.io/v3/" + configVariable("INFURA_API_KEY"),
},
},
},
plugins: [HardhatViem, HardhatIgnitionViem],
};
export default config;
2.2 关键配置变更对照表
| 配置项 | v2版本 | v3版本 |
|---|---|---|
| Solidity配置 | solidity: "0.8.17" | solidity: { profiles: { default: { compilers: [{ version: "0.8.22" }] } } } |
| 网络配置 | networks: { goerli: { url, accounts } } | networks: { goerli: { type: "http", url, accounts } } |
| 环境变量 | process.env.* | configVariable("VAR_NAME") (通过keystore管理) |
| 插件导入 | 单独导入插件包 | 导入插件类并在plugins数组中注册 |
| 路径配置 | paths: { sources: "contracts" } | paths: { tests: { mocha: "test/mocha", nodejs: "test/node" } } |
2.3 配置变量管理
Hardhat 3.0引入了安全的配置变量管理系统,替代了传统的环境变量方式:
# 设置配置变量
pnpm hardhat keystore set INFURA_API_KEY
pnpm hardhat keystore set PRIVATE_KEY
# 查看所有变量
pnpm hardhat keystore list
在配置文件中通过configVariable("VAR_NAME")引用,避免了敏感信息泄露风险。
三、插件生态系统迁移
3.1 核心插件替换指南
Hardhat 3.0重构了插件系统,以下是常用插件的迁移对照表:
| v2插件 | v3替代方案 | 迁移说明 |
|---|---|---|
@nomiclabs/hardhat-ethers | @nomicfoundation/hardhat-ethers | 支持ethers v6,API基本兼容 |
@nomiclabs/hardhat-waffle | @nomicfoundation/hardhat-ethers-chai-matchers | 仅保留Chai断言功能 |
hardhat-deploy | @nomicfoundation/hardhat-ignition-viem | 需重构部署脚本为Ignition模块 |
@nomiclabs/hardhat-etherscan | @nomicfoundation/hardhat-verify | 验证API完全重构 |
hardhat-gas-reporter | 内置支持 | 通过REPORT_GAS=true环境变量启用 |
3.2 Ignition部署系统迁移
Ignition是Hardhat 3.0引入的新一代部署系统,替代了传统的部署脚本。以下是从部署脚本迁移至Ignition模块的示例:
传统部署脚本:
async function main() {
const [deployer] = await ethers.getSigners();
console.log("Deploying contracts with the account:", deployer.address);
const Token = await ethers.getContractFactory("Token");
const token = await Token.deploy(1000000);
await token.deployed();
console.log("Token deployed to:", token.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Ignition模块:
import { buildModule } from "@nomicfoundation/ignition-core";
export default buildModule("TokenModule", (m) => {
const token = m.contract("Token", [1000000]);
return { token };
});
部署命令:
# 传统部署
npx hardhat run scripts/deploy.ts --network goerli
# Ignition部署
npx hardhat ignition deploy ignition/modules/TokenModule.ts --network goerli
3.3 测试框架迁移
Hardhat 3.0支持两种测试框架:传统的Mocha和新的Node.js原生测试框架。以下是迁移示例:
Mocha测试(兼容v2):
import { expect } from "chai";
import { ethers } from "hardhat";
describe("Token", function () {
it("Should mint tokens correctly", async function () {
const Token = await ethers.getContractFactory("Token");
const token = await Token.deploy(1000000);
await token.deployed();
expect(await token.totalSupply()).to.equal(1000000);
});
});
Node.js测试(v3新特性):
import { test } from "node:test";
import { expect } from "@nomicfoundation/hardhat-chai-matchers-viem";
import { deployContract } from "@nomicfoundation/hardhat-viem";
import { viem } from "hardhat";
import TokenArtifact from "../artifacts/contracts/Token.sol/Token.json";
test("Token should mint tokens correctly", async () => {
const token = await deployContract(viem, TokenArtifact, [1000000]);
expect(await token.read.totalSupply()).toBe(1000000n);
});
四、迁移实施步骤
4.1 迁移流程图
4.2 详细迁移步骤
步骤1:环境准备
# 升级Node.js (使用nvm)
nvm install 20 --lts
nvm use 20
# 安装pnpm (推荐)
npm install -g pnpm
步骤2:项目初始化
# 克隆项目
git clone https://gitcode.com/GitHub_Trending/ha/hardhat
cd hardhat
# 安装依赖
pnpm install
pnpm build
步骤3:配置迁移
# 创建新的配置文件
mv hardhat.config.ts hardhat.config.v2.ts
touch hardhat.config.ts
# 根据v3语法重构配置文件
# 参考2.1节的配置示例
步骤4:依赖迁移
# 卸载旧插件
pnpm remove @nomiclabs/hardhat-ethers @nomiclabs/hardhat-waffle
# 安装新插件
pnpm add -D @nomicfoundation/hardhat-viem @nomicfoundation/hardhat-ignition-viem
步骤5:部署脚本迁移
# 创建Ignition模块目录
mkdir -p ignition/modules
# 将部署脚本转换为Ignition模块
# 参考3.2节的示例
步骤6:测试验证
# 运行编译
pnpm hardhat compile
# 运行测试
pnpm hardhat test
# 部署到测试网络
pnpm hardhat ignition deploy ignition/modules/TokenModule.ts --network edrGoerli
五、常见问题解决方案
5.1 编译错误:找不到模块 '@nomiclabs/hardhat-ethers'
问题原因:旧插件未完全移除。
解决方案:
# 清理node_modules和依赖缓存
rm -rf node_modules pnpm-lock.yaml
pnpm install
# 确保配置文件中已移除旧插件引用
5.2 部署错误:"HardhatIgnition: Module not found"
问题原因:Ignition模块路径错误。
解决方案:
# 检查模块路径是否正确
ls ignition/modules
# 确保使用正确的部署命令
pnpm hardhat ignition deploy ignition/modules/TokenModule.ts --network goerli
5.3 测试错误:"viem is not defined"
问题原因:未正确导入viem实例。
解决方案:
// 在测试文件顶部添加
import { viem } from "hardhat";
5.4 性能问题:编译速度比v2慢
问题原因:EDR引擎缓存未启用。
解决方案:
// 在hardhat.config.ts中添加
export default {
// ...
edr: {
cache: true,
cacheDir: ".edr-cache"
}
}
六、迁移后优化建议
6.1 性能优化配置
// hardhat.config.ts
export default {
solidity: {
profiles: {
default: {
compilers: [{
version: "0.8.22",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
}],
},
},
},
edr: {
cache: true,
forkCache: true,
performance: {
parallelCompilation: true,
maxConcurrentCompilations: 4
}
}
};
6.2 新功能使用建议
- EDR模拟网络:使用
edr-simulated网络类型获得更快的fork测试体验:
networks: {
edrMainnet: {
type: "edr-simulated",
forking: {
url: "https://mainnet.infura.io/v3/" + configVariable("INFURA_API_KEY"),
blockNumber: 18000000
}
}
}
- Ignition高级功能:使用create2部署实现确定性地址:
import { buildModule } from "@nomicfoundation/ignition-core";
import { create2Strategy } from "@nomicfoundation/ignition-viem";
export default buildModule("DeterministicTokenModule", (m) => {
const token = m.contract("Token", [1000000], {
strategy: create2Strategy({
salt: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
})
});
return { token };
});
- 配置变量加密存储:使用keystore管理敏感配置:
# 设置加密存储
pnpm hardhat keystore set PRIVATE_KEY --encrypt
# 使用时需要解密
pnpm hardhat keystore get PRIVATE_KEY --decrypt
七、总结与展望
Hardhat 3.0通过EDR引擎、Ignition部署系统和类型化配置带来了显著的开发体验提升。迁移过程虽然涉及配置重构和插件更新,但长期来看将大幅提高开发效率和项目可维护性。
迁移后,开发者应重点关注:
- 利用Ignition的声明式部署简化复杂部署流程
- 采用Node.js测试框架提升测试性能
- 使用EDR模拟网络加速测试迭代
- 利用配置变量系统增强项目安全性
随着Hardhat生态的不断发展,建议保持关注官方更新,特别是Ignition模块系统和EDR引擎的持续优化。
附录:迁移检查清单
环境检查
- Node.js版本 ≥ v20.0.0
- pnpm版本 ≥ v8.0.0
- TypeScript版本 ≥ v5.0.0
配置迁移
- 重构
hardhat.config.ts为v3类型化配置 - 迁移网络配置至新格式
- 使用
configVariable替代环境变量 - 配置Solidity编译器profiles
插件迁移
- 替换所有
@nomiclabs/插件为@nomicfoundation/版本 - 移除已废弃插件(如hardhat-waffle)
- 添加Ignition相关插件
代码迁移
- 将部署脚本转换为Ignition模块
- 更新测试代码适配新断言库
- 替换ethers v5 API为v6语法
验证步骤
- 运行
pnpm hardhat compile验证编译 - 运行测试套件验证功能正确性
- 部署至测试网络验证部署流程
- 验证合约验证功能正常工作
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



