@wagmi/cli 版本演进与技术全景:从 ABI 代码生成到插件化开发工作流
【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi
@wagmi/cli 是 wagmi 生态中负责“基于智能合约 ABI 自动生成类型安全代码”的命令行工具,核心能力是init与generate两个命令,配合可插拔的 Foundry、Hardhat、Etherscan、Sourcify 等插件,把合约源码、部署记录或区块链浏览器上的已验证 ABI 自动转化为可直接导入的 TypeScript/JavaScript 文件。本文以仓库内 packages/cli/CHANGELOG.md 的完整版本历史为骨架,结合 packages/cli/src 下的命令、配置与各插件源码,逐版本梳理其功能演进、破坏性变更与底层实现,帮助读者既掌握 CLI 的配置与使用方式,也理解每个版本改动背后的技术动机。
一、CLI 整体架构:两个命令 + 一份配置 + 插件矩阵
从 packages/cli/src/cli.ts 可以看到,CLI 基于cac构建,仅暴露两个子命令:
wagmi generate:读取配置文件,解析合约并生成代码,支持-c/--config指定配置文件路径、-r/--root指定解析配置的根路径、-w/--watch监听文件变化持续重新生成;wagmi init:在项目中创建默认配置文件,同样支持-c与-r。
init会根据项目是否使用 TypeScript 来决定生成wagmi.config.ts还是wagmi.config.js(见 packages/cli/src/commands/init.ts),TS 项目生成import { defineConfig } from '@wagmi/cli'的形式,JS 项目则生成带// @ts-check与 JSDoc 类型注释的 CommonJS/ESM 配置。generate的完整流水线在 packages/cli/src/commands/generate.ts 中:先定位并解析配置文件(findConfig/resolveConfig),检测项目是否使用 TypeScript,然后校验插件、收集合约(配置中的contracts与各插件contracts()的并集)、按名称排序去重,最后依次执行插件run()得到imports、prepend、content,拼装后经format格式化写入config.out指定的输出文件。源码中还明确了两条强约束:out是必填项且多个配置的out必须唯一,合约name也必须是唯一的,否则直接报错。
配置体系的类型定义在 packages/cli/src/config.ts:Config由contracts(ContractConfig[])、out(输出路径)、plugins(Plugin[])三部分组成,defaultConfig的默认输出是src/generated.ts。ContractConfig支持abi、name以及单地址或多链地址对象({ [chainId]: address })。Plugin接口则规定了五个可选钩子:contracts()提供合约、run()生成代码、validate()校验环境、watch配置文件监听(含paths、onAdd、onChange、onRemove、command)。
二、从 0.1.0 到 1.0.0:CLI 的诞生与框架基础
CHANGELOG 记录的起点是 0.1.0(Initial release),此后的 0.1.x 版本集中在三件事:插件生态补全、多包管理器兼容与代码生成正确性。
- 插件层面:0.1.2 为
etherscan插件加入 celoscan 支持;0.1.7 新增 Sourcify);0.1.4 起project变为 Foundry 插件的可选参数,0.1.3 则实现了 Foundry 配置文件(foundry.toml的out)的自动探测(见 packages/cli/src/plugins/foundry.ts 中通过forge config --json读取out/src的实现)。 - 包管理器兼容:0.1.8 / 0.1.9 针对 yarn@^3 与 npm 的包检测做了专门修复,0.1.15 修复了 npm 下使用 Hardhat 插件的问题;2.1.16 又进一步修复了 Bun 场景的包检测(对应 packages/cli/src/utils/packages.ts)。
- 代码生成正确性:0.1.1 修复生成地址对象 key 的类型,0.1.10 修复生成 read hooks 的
select类型,0.1.11 让 React 插件使用Address类型而非硬编码`0x{string}`。
0.1.12 是一次重要的内部重构——CLI 内部实现从 ethers 迁移到 viem,这也为后续@wagmi/chains被viem/chains取代(1.5.0)埋下伏笔。1.0.0 正式发布时(对应 CHANGELOG 中 1.0.0 条目),同时包含config.setConnectors等新能力(见 1.0.0-next.5),并在此后的小版本中持续打磨:1.2.0 将Address类型导入从 ABIType 切换到 viem,1.4.0 为生成的useContractReadhook 增加默认 chain ID 并实现确定性(Deterministic)输出,1.4.1/1.5.2 修复 esbuild 版本与 ESM 下 prettier 的 require 问题。
三、Wagmi CLI 2.0:命令、命名与生成的全面重构
CHANGELOG 中标注为Major Changes的 2.0.0(对应 #3333)是 v1 到 v2 的里程碑式重构,官方同步发布了迁移指南。从源码可以还原 2.0 之后的新面貌:
- 命令收敛:packages/cli/src/cli.ts 只保留
generate与init两个命令,并加入“未知命令”错误提示(该项能力实际源自 1.0.2); - 命名生成器可定制:React 插件的
getHookName支持函数式自定义命名,Actions 插件的getActionName同理,二者都提供'legacy'模式以兼容旧命名(见 packages/cli/src/plugins/react.ts 中默认命名规则:默认生成useRead<Contract>...,'legacy'则生成use<Contract>Read等); - 包名覆盖:Actions 插件的
overridePackageName可强制从@wagmi/core/codegen或wagmi/codegen导入,未指定时按已安装包自动探测(见 packages/cli/src/plugins/actions.ts); - 确定性输出:1.4.0 引入、2.x 延续的按名称升序排序(
new Map([...contractMap].sort()))保证同一份 ABI 在任何机器上生成结果一致,便于版本管理与 CI 比对。
此外 2.0.x 修复了几个代码生成细节:2.0.2 修复合约事件 watch hooks 的 prop 名,2.0.3 修复 actions 插件中合约事件 action 误用functionName而非eventName的问题。
四、插件能力演进(2.1.x → 2.10.0):链支持、API 升级与配置项新增
2.1.x 到 2.10.0 是插件功能的高频迭代期,几乎每条变更都能在 packages/cli/src/plugins 中找到对应实现:
4.1 Etherscan 插件:从 API v1 到 API v2 与代理合约支持
Etherscan 插件基于通用的 blockExplorer.ts 工厂实现,核心是向?module=contract&action=getabi发起请求并按status: '1'/'0'判别响应。其演进脉络包括:
- 2.1.2 加入 Arbitrum Sepolia、Fraxtal、Holesky 测试网,2.1.3 用 SnowScan 替换已废弃的 SnowTrace,2.1.4 加入 Gnosis,2.1.6 加入 basescan,2.1.8 加入 Blast,2.1.18 加入 Polygon Amoy,2.1.22 加入 Sonic;
- 2.2.0 是功能转折点:升级到 Etherscan API v2,并新增
tryFetchProxyImplementation标志——开启后优先获取代理合约(Proxy)背后实现合约(Implementation)的 ABI,而不是代理自身的 ABI。这在面对可升级合约(UUPS/Transparent Proxy)时尤为关键,生成的代码才能调用真正的业务函数; - 2.7.0 / 2.7.1 持续更新插件所支持的链集合(对应仓库内 scripts/updateBlockExplorerPluginChains.ts 的自动化维护流程)。
4.2 Sourcify 插件:升级到 v2 API
2.3.0 将sourcify插件升级到 Sourcify v2 API(实现位于 packages/cli/src/plugins/sourcify.ts),2.1.10 与 2.1.18 则分别更新其内部实现与新增 Polygon Amoy 支持。
4.3 Foundry 插件:includeBroadcasts自动部署映射
Foundry 插件(packages/cli/src/plugins/foundry.ts)是使用频率最高的插件,它通过forge config --json解析out/src,默认排除 OpenZeppelin 的Base.sol、Common.sol、MockERC20.sol、console.sol、Vm.sol以及脚本/测试产物(**.s.sol、**.t.sol)等大量模板文件(foundryDefaultExcludes),并支持artifacts、deployments、include、exclude、namePrefix、project与forge子配置(clean、build、path、rebuild)。其版本变化包括:
- 2.1.9 / 2.1.12 两度更新默认排除项;
- 2.1.14 修复
exclude选项在 Foundry 与 Hardhat 插件中被忽略的缺陷; - 2.9.0 新增
includeBroadcasts:开启后插件会扫描broadcast/目录下的所有run-latest.json,提取CREATE/CREATE2类型的交易(含additionalContracts),按路径片段解析 chainId,自动构建{ [contractName]: { [chainId]: address } }形式的部署映射;显式传入的deployments映射优先级更高,可覆盖广播记录。
4.4 React 插件:abiItemHooks开关与命名定制
React 插件(packages/cli/src/plugins/react.ts)按 ABI 条目生成createUseReadContract、createUseWriteContract、createUseSimulateContract、createUseWatchContractEvent的包装 hooks,并按view/pure、nonpayable/payable、event自动分类。2.8.0 新增abiItemHooks选项(默认true):置为false时只为每个合约生成一个聚合 hook,而不再为 ABI 中每个函数/事件单独生成 hook,大幅缩减生成文件体积。getHookName函数式配置则允许完全自定义 hook 命名。
4.5 fetch 插件与 Routescan 插件的“进与退”
fetch是 blockExplorer、etherscan、sourcify 等插件的底层基座(packages/cli/src/plugins/fetch.ts),负责带缓存的 HTTP 拉取。2.3.2 修复了 fetch 出错时未清除 timeout 的隐患,避免长驻进程中的定时器泄漏。routescan插件 2.4.0 加入(支持测试网见 2.5.0),但在2.10.0 被移除(破坏性变更):官方明确该插件的前赞助商身份已结束,如需继续使用可自行将旧版 routescan.ts 源码 vendor 进项目。这是阅读 CHANGELOG 时最值得注意的破坏性变更之一。
五、代码生成质量与工程化细节的持续打磨
除功能外,CHANGELOG 还记录了 CLI 在工程质量上的迭代,这些细节直接关系到生成代码的可用性:
syncConnectedChain修复:2.5.1 修复 codegen 生成的 actions/hooks 中syncConnectedChain: false不生效的问题,确保多链场景下 hook 不因链切换而意外失效;- TypeScript 严格模式兼容:2.1.15 改进对
exactOptionalPropertyTypes的支持,2.1.0 新增对 TypeScript 版 CLI 配置的解析以决定是否允许生成 TS 输出,2.1.5 还拓宽了 TypeScript 的检测范围(相关实现见 packages/cli/src/utils/getIsUsingTypeScript.ts); - 进程行为:2.1.5 为 CLI 进程添加标题(
process.title = 'node (wagmi)'),2.1.13 修复长驻进程下generate不退出、2.1.19 用nanospinner替换ora减少依赖体积,2.1.20 / 2.1.21 分别移除fs-extra与内部依赖依赖,2.6.0 统一升级内部依赖。
这些改动共同保证了 CLI 在 CI、watch 长驻与严格类型检查项目中的稳定性。
六、仓库内的配套资源
如果想深入实践,仓库提供了多个可直接对照的入口:
- 配置与命令的测试:packages/cli/src/commands/generate.test.ts、packages/cli/src/commands/init.test.ts;
- 各插件测试与快照:packages/cli/src/plugins/foundry.test.ts、packages/cli/src/plugins/react.test.ts、packages/cli/src/plugins/snapshots;
- 完整可运行示例:playgrounds/vite-react/wagmi.config.ts(配套 playgrounds/vite-react/src/contracts.ts 展示生成产物形态)、playgrounds/vite-vue/wagmi.config.ts;
- 插件链支持维护脚本:scripts/updateBlockExplorerPluginChains.ts。
安装方式简单(pnpm add @wagmi/cli,见 packages/cli/README.md),随后执行wagmi init生成配置、wagmi generate生成代码即可。
七、小结:如何阅读这份 CHANGELOG
把 CHANGELOG 与源码对照阅读,可以得到清晰的演进脉络:0.1.x搭建了插件工厂与包管理器兼容的基础;1.x完成 ethers→viem 的内部迁移并确立确定性输出;2.0重构了命令与命名体系,getHookName/getActionName/overridePackageName让生成行为完全可定制;2.1~2.9是插件能力的密集增强(API v2、代理合约 ABI、广播部署映射、abiItemHooks);2.10则以移除routescan插件为标志,提醒使用者关注赞助驱动的插件可能随合作终止而被移除。理解这些版本节点,既能帮助你在升级@wagmi/cli时预判破坏性变更,也能在阅读生成代码与排查问题时快速定位对应实现。
【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考