CodeMod 代码重构/升级必知必会

2023-10-23 14:26:24 浏览数 (1)

CodeMod(Code Modification) 的应用场景非常多,我在过去几年就使用 ‘codemod‘ 升级过多个项目,节省了大量的人力成本:

  • 将原生微信小程序转换到 Taro; 后面又从 Taro 2 升级到 Taro 3
  • Sonar / Eslint 问题修复。
  • 前端多语言自动提取

除此之外,codemod 也可以用在以下场景:

  • 框架升级,比如 Next.js 升级、Vue 3 升级
  • 语言升级,将废弃的旧语法替换从新语法
  • 代码格式化
  • API 重构
  • 代码检查等等

如果你有这方面的需求,那这篇文章很适合你。


前置知识:你需要对编译原理有基本了解,如果你感到吃力,可以看看我之前写的文章:深入浅出 Babel 上篇:架构和原理 实战

编写一个代码升级/重构程序主要涉及以下环节:

这里每个环节都有很多库/方案可以选择,比如:

  • 文件查找: 可以使用 Glob 通配符库来查找或忽略文件,比如 node-glob、fast-glob、globby 等
  • AST parse: 这个需要根据特定的语言进行选择。比如 JavaScript 可以选择 Babel(推荐)、EsprimaAcornswc;CSS 可以使用 postcsslightning css;Vue SFC 可以使用其官方的 vue-template-parser 等等。更多方案,可以探索一下 AST Explorer,这里列举了市面上主流的 Parser
  • AST Transform: 将 AST 解析出来之后,可以根据自己的需求来改写 AST。不同语言/parser 处理规则会有较大的差异。AST parse 和 transform 可以选择一些工具来简化工作,比如 Jscodeshiftgogocode,本文接下来会深入讲解这些工具。
  • Code Generate: 将 AST 转换为代码。我们要尽可能地维持原有的代码格式,否则代码 Diff 会很难看。这个阶段可以选择 recast 这类方案,它可以尽量维持代码的原有格式;另一种方案就是使用代码格式化工具,比如 prettiereslint,也可以最大限度维持代码的格式。
  • 写入代码: 调用 fs 写入。

将这些东西串起来,你可能还需要一些库,帮你快速编写命令行工具,例如 yargs、commander、inquirer.js

接下来我将介绍 codemod 这个领域一些主流的库,这些库都各有所长,有些提供了一整套的流程,有些则提供了更高效的 AST 查找和替换方法。

Recast

recast 是一个知名的库,很多 CodeMod 工具都是基于它来实现的。我们通常将它作为 JavaScript 的 AST 转换器非破坏(nondestructive)代码格式化工具来使用。

简单说就是使用 recast 进行’代码生成‘可以最大程度地保持代码原本的格式

0 人点赞