127 - 《框架级 codemod:一》
不知大家是如何面对框架和库的大版本更新的,比如升级 Umi 3 到 4,如果有提供一个一键升级的 codemod 工具,会不会感觉很爽?
社区库的大版本更新通常会有升级文档,但却比较少见到有「一键升级工具」,即通过一条命令完成全部升级;而企业内的框架则通常会提供。提供和不提供都是出于 ROI 的考虑。比如基于 Umi 的蚂蚁内框架 Bigfish,服务了数千个活跃项目,每个项目都按照文档进行一遍升级,成本就要乘以数千。所以虽然 codemod 的开发成本高,但在这个场景下,ROI 还是划算的。
我们最近实现了面向内网框架的 3 升 4 的 codemod,目前在收尾和验证阶段,顺利的话会考虑对外提供。
codemod 背后如何实现?
社区有个库叫 jscodeshift,在 https://t.zsxq.com/3ZbUf2J 还调研过,但我们最终没有用他。jscodeshift 适用于纯 js 或 ts 代码的改动,比如 react 的 class component 转 function component,用 jscodeshift 是合适的。但对于框架而言,其实远远不够。因为修改的点除了 js 或 ts,还有 package.json、配置、css、eslintrc、prettierrc 等。并且这些修改之间还是有关联的,比如如果有配置 a,改成配置 b,然后做 js 的修改,最后还要在 package.json 中加上某个依赖。
我们实现的 codemod 分 preparer、checker 和 runner 三个阶段。
preparer 是准备给 checker 和 runner 用的 context,包括各种配置、pkg 信息、文件信息、基于前面的分析结果等。配置不能直接 require,我是用 aot 的方式,用 esbuild externals 所有依赖后 bui