与 Hardhat 集成
可以让您的 Foundry 项目与 Hardhat 一起工作。 这假设您有一个正在运行的 Foundry 项目并且想要添加 Hardhat,并且你很熟悉 Hardhat。
为什么这不能开箱即用?
默认情况下,Hardhat 希望将库安装在 node_modules
中,这是所有 NodeJS 依赖项的默认文件夹。 Foundry 希望它们在 lib
中。 当然 我们可以配置 Foundry 但不容易配置到 node_modules
的目录结构。
因此,推荐的设置是使用 hardhat-preprocessor。 顾名思义,Hardhat-preprocessor 是一个 Hardhat 插件,它允许我们在合约通过 Solidity 编译器运行之前对其进行预处理。
我们使用它来修改 Solidity 文件中的导入指令,以在 Hardhat 尝试编译它们之前根据 Foundry remappings.txt
文件解析库的绝对路径。 这当然只是发生在内存中,所以你实际的 Solidity 文件永远不会改变。 现在,Hardhat 很乐意使用您随 Foundry 安装的库来遵循和编译。
给我看看示例repo!
如果您想将其改编为您已有的 Foundry 项目或了解其工作原理,请阅读以下内容:
指示
在您的 Foundry 项目工作目录中:
npm init
- 照常设置您的项目详细信息。npm install --save-dev hardhat
- 安装 Hardhat。npx hardhat
- 在同一目录中设置您认为合适的 Hardhat 项目。forge remappings > remappings.txt
- 每次在 Foundry 中修改库时都需要重新运行它。
现在您需要对 Hardhat 项目进行以下更改。 以下假定 TypeScript 设置:
npm install --save-dev hardhat-preprocessor
- hardhat-preprocessor 的详细信息- 添加
import "hardhat-preprocessor";
到您的hardhat.config.ts
文件。 - 确保存在以下函数(您可以将其添加到您的
hardhat.config.ts
文件或其他地方并导入它 - 还要确保import fs from "fs";
存在于添加的文件中) :
function getRemappings() {
return fs
.readFileSync("remappings.txt", "utf8")
.split("\n")
.filter(Boolean) // remove empty lines
.map((line) => line.trim().split("="));
}
感谢 @DrakeEvansV1 和 @colinnielsen 提供此片段
- 将以下内容添加到导出的
HardhatUserConfig
对象中:
...
preprocess: {
eachLine: (hre) => ({
transform: (line: string) => {
if (line.match(/^\s*import /i)) {
for (const [from, to] of getRemappings()) {
if (line.includes(from)) {
line = line.replace(from, to);
break;
}
}
}
return line;
},
}),
},
paths: {
sources: "./src",
cache: "./cache_hardhat",
},
...
现在,Hardhat 应该可以很好地与 Foundry 配合使用。 您可以运行 Foundry 测试或 Hardhat 测试/脚本并访问您的合约。
在现有的 Hardhat 项目中使用 Foundry
假设您已经有一个 Hardhat 项目,其中包含一些依赖项,例如目录 node_modules/
中的@OpenZeppelin/contracts
。
您可以通过 4 个步骤在此项目中使用 Foundry 测试。
在我们开始之前,让我们看一下目录:
- 合约在“合约”中
- Hardhat 单元测试在
test
中,我们会将 Foundry 测试文件放在test/foundry
中 - Hardhat 将其缓存放在
cache
中,我们将把 Foundry 缓存放在forge-cache
中
添加Foundry测试的4个步骤
- 将新创建的空 Foundry 项目中的 lib/forge-std 复制到 Hardhat 项目目录中。 注意:您还可以运行
forge init --force
在这个非空目录中初始化一个 Foundry 项目,并删除由 Foundry init 创建的不需要的目录。 - 将
foundry.toml
配置复制到这个Hardhat 项目目录,并更改其中的src
、out
、test
、cache_path
:
[profile.default]
src = 'contracts'
out = 'out'
libs = ['node_modules', 'lib']
test = 'test/foundry'
cache_path = 'forge-cache'
# See more config options https://book.getfoundry.sh/reference/config.html
- 创建一个
remappings.txt
使 Foundry 项目与 VS Code Solidity 扩展一起工作:
ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
查看有关 remappings.txt
和 VS Code Solidity 扩展的更多信息:Remapping dependencies, Integrating with VSCode
- 创建一个子目录
test/foundry
并在其中编写 Foundry 测试。
让我们将示例测试文件 Contract.t.sol
放在这个目录中并运行 Foundry 测试
forge test
现在,Foundry测试可以在这个现有的 Hardhat 项目中进行。 由于 Hardhat 项目没有被触及,它可以像以前一样工作。