大家好,欢迎来到IT知识分享网。
将一个庞大的 JavaScript 代码库迁移到 TypeScript 通常不是一项简单的任务。本文详细介绍了如何在六周内成功完成这一迁移,并避免了任何生产环境中的中断。对于开发团队来说,这一过程不仅需要处理庞大的代码量和复杂的环境配置,还要确保迁移后的稳定性与代码质量的提升。通过本文,也希望能给想要将自己项目迁移到 TypeScript 的开发者提供宝贵的参考与经验。
原文链接:
https://benhowdle.im/migrating-js-to-ts-zero-downtime.html
责编 | 苏宓
以下为译文:
TypeScript 已成为构建强大、易于维护和可扩展的 JavaScript 应用程序的事实标准。但是,将一个庞大的生产环境代码库迁移到 TypeScript 绝不是件简单的事,尤其是当我们面对 16 万行关键业务的 JavaScript 代码,而且系统中还涉及到真实用户和他们的税务申报。
尽管挑战巨大,我们还是决定迎接这个挑战。我们相信,虽然过程艰难,但从长远来看,这绝对值得。因此,我们在六周内完成了整个代码库的迁移,且没有任何停机时间。接下来,分享一下我们是怎么做的,过程中遇到的挑战,以及一些帮助我们成功迁移的工具。
挑战:大规模迁移,零宕机
在处理大规模生产应用时,最怕的就是停机。我们的应用程序负责提供重要的金融和银行服务,任何中断都会直接影响到客户。我们也清楚 TypeScript 带来的长期好处——它能让开发更顺畅、代码更容易维护,而且更安全,这些都值得我们付出这番努力。
在规划将生产环境中的 JavaScript 代码迁移至 TypeScript 时,我们遇到的主要挑战有:
- 零宕机要求:在迁移过程中,我们不能停下手头的工作,必须继续发布新特性和修复问题。毕竟我们还是一个处于种子阶段的初创公司,第一批忠实用户的体验至关重要,我们不能让他们受到影响,因为他们的生计和我们的系统息息相关。
- 16 万行代码:这不是一个轻松的周末项目,面对这么庞大的代码量,我们必须采取有计划、有策略的方法。我们的 API 是一个纯 Node.js Express 应用,提供 GraphQL API,还涉及 WebSocket 服务器。
- 多个环境:代码同时运行在 AWS Lambda Worker 和 ECS 上的 Node.js GraphQL API 中,一个小错误就可能影响到多个服务和用户。所以必须小心翼翼,确保每一步都稳妥。
迁移策略:保持独立分支
顺利完成迁移的关键就是保持一个独立的分支。我们是这样做的:
- 创建迁移分支:我们创建了一个专门的分支,把所有的 .js 文件改成 .ts。这个分支就像我们的实验场,逐步引入 TypeScript。当时我担任 CTO,所以负责全盘协调,放下特性开发和修复的工作,专心推进迁移。对初创公司来说,想从“赶紧上线”的紧迫状态中跳出来,投入时间做长远的工作其实挺难的,但这次迁移我非常确信是值得的。
- 定期更新合并:为了跟得上主分支上的新特性,我们定期把迁移分支和主分支合并,确保最后合并时不会有冲突。每次合并,我只需要把新增加的 .js 文件转换成 .ts 文件,因为我在 TypeScript 编译时设置了不同的输出目录。
- 逐步引入类型:我们从最重要的模块开始,逐步让代码支持 TypeScript 的类型检查。一个比较繁琐的任务是将所有的 require() 调用改成更现代的 import/export 语法。我记得第一次尝试编译 TypeScript 时,出现了超过 1000 个错误,大部分都是独立的错误。面对这些错误时,你只能耐心地一个一个解决掉。
- 持续集成(CI)验证: 每次合并更新都会触发 CI 流水线,运行所有测试,确保 TypeScript 版本的稳定性。我们还用了 Jest 和 Checkly 监控测试,确保代码没有问题。
测试与准备:确保零宕机
在 TypeScript 编译没有错误且所有测试通过后,我们将 TypeScript 版本部署到预发布环境。接下来我们做了以下几步:
- 2-3 天的全面测试:
在预发布环境中,我们对应用做了严格的测试,使用 Checkly 监控它的正常运行时间,确保没有出现回归问题。
说实话,我无法想象在没有任何正常运行时间监控的情况下就把应用直接放到生产环境——Checkly 真的是一个超棒的选择,我一有机会都会向周围朋友、开发者推荐这款工具。
我们不仅监控了 API 的基本正常运行情况,还设计了一些专门的检查,确保系统中的一些关键操作(比如注册、登录和资金流动)正常运行。资金流动的检查只在预发布环境做,以避免出现太多会计上的混乱和噪音。比如,你可以用一个简单的沙漏计时器(就是那种倒过来开始计时的沙漏)来模拟资金流动:设置两个银行账户,互相转账 $1 直到其中一个账户余额为零,然后再从另一个账户把钱转回来,基本上就是在创建自己的“资金流动心跳”。
- 环境一致性:
我们把 AWS 上所有的 Lambda Workers 和 ECS 上的 Node.js GraphQL API 都切换到了预发布环境中的 TypeScript 版本,这样和生产环境几乎一模一样。这个过程还挺有意思的。
我们的 Lambda workers 原本是指向现有的 JavaScript 源文件运行,但部署新版本后,原来的文件就不存在了。所以我在 CDK 配置文件里加了一行条件代码,让 Docker 知道,如果新编译的 TypeScript-JavaScript 文件存在,就运行它;如果不存在,就退回使用原来的 JavaScript 文件,这样就能避免多步部署过程中可能出现的问题。代码大概是这样的:
cmd: [
'sh',
'-c',
`[ -f src/workers/${props.folderName}/move-money.js ] && node src/workers/${props.folderName}/move-money.js || node lib/workers/${props.folderName}/move-money.js`,],
这样,即使是使用原始的 JavaScript 文件,workers 也能以某种方式保持可用。下次部署时,我们就可以安全地移除这行条件代码。
- 零停机部署:
通过预发布环境的测试,我们对部署生产环境充满信心。部署顺利进行,没有任何停机或故障。
结果:提升的开发者体验与修复的漏洞
结果立竿见影:
- 开发者体验(DX)提升:
TypeScript 提升了编辑器支持和重构能力,极大地提升了开发者的生产力和工作满意度。
- 漏洞检测:
TypeScript 编译器捕获了一些在 JavaScript 版本中未被发现的漏洞,提高了应用程序的整体稳定性。从一开始就有了好结果。
迁移过程中使用的工具和扩展
在迁移过程中,多个 VSCode 扩展和工具显著简化了我们的工作:
- ESLint + TypeScript 支持:用于保证一致的代码质量和规范检查。
- TypeScript Hero 和 TypeScript Import Sorter:用于自动整理导入项。
- ts-migrate 和 jscodeshift:用于自动化一些重复的任务。
- Checkly:用于预发布环境中的端到端监控和正常运行时间检查。
结论:值得吗?
绝对值得!迁移到 TypeScript 是一次具有挑战性但非常值得的努力。它不仅改善了开发者体验,还提升了代码库的稳定性和可维护性。得益于战略性规划、强大的 CI/CD 流水线和合适的工具,我们顺利完成了迁移。捕捉那些低级错误的反馈循环减少了十倍。
如果你也在考虑将一个大规模的生产应用迁移到 TypeScript,不妨试试。长期来看,这笔投入是值得的。
「2025 全球机器学习技术大会」将于 4 月 18-19 日在上海虹桥西郊庄园丽笙大酒店隆重召开。本届大会的主会环节汇聚全球顶级学者与业界领袖,加拿大工程院及加拿大皇家学院院士、微众银行首席人工智能顾问杨强,IEEE Fellow、清华大学人工智能研究院副院长、生数科技创始人兼首席科学家朱军,数势科技创始人兼CEO、原京东集团副总裁、原京东商城技术负责人黎科峰,CSDN 高级副总裁、Boolan 首席技术专家李建忠等重磅嘉宾将悉数登场并发表主题演讲。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/183464.html