Migrating a Large Flow Monorepo to TypeScript
Bài tóm tắt Yelp 2026 4. Điều chỉnh Độ khó: Trung bình
Yelp · 2026 · 4. Điều chỉnh · Độ khó: Trung bình — bài gốc
Đối chiếu với Stripe 2022: cùng bài toán, Stripe chuyển một lần.
Bối cảnh
- Đầu 2017, đội Webcore chọn Flow thay vì TypeScript (lúc đó Flow hỗ trợ React và hiệu năng tốt hơn). Vài năm sau TypeScript rõ ràng thắng: nhiều kiểu cho package npm hơn hẳn, ổn định hơn.
- Mục tiêu số một là giữ niềm tin vào type checking: không "tạm tắt" kiểm tra, không chèn hàng loạt comment bỏ qua. Theo Yelp, code đã mất độ phủ của type checker, test hay linter gần như không bao giờ lấy lại được. Điều này loại cách viết lại một lần (codemod không đủ tốt cho hơn một triệu dòng trong kỳ nghỉ) và loại cả đóng băng code.
Thay đổi chính
- Từng package một trong monorepo Lerna:
flowts(cộng codemod riêng) chuyển code, phần còn lại sửa tay; sau khi chuyển,flowgenbiến.d.tsthành header Flow để code Flow phía dưới vẫn kiểm được kiểu. Theo họ, chính việc trước đó gom mọi JavaScript vào một monorepo cho phép đổi công cụ cho cả hệ sinh thái bằng một PR và chỉ phải lo interop ở mức package. - Không ra mắt vội: công cụ đã chạy được giữa 2022 nhưng họ dogfood thêm nhiều tháng, chuyển khoảng 90 package nền (cùng đội Design Systems) để sửa lỗi công cụ và để team sau không phải chờ phụ thuộc. Ra mắt cho các team tính năng 5/2023, kèm thuyết trình theo từng vùng, demo trực tiếp, và dashboard EE Metrics cho biết package nào chuyển được.
- Tiến độ: khoảng 100 package lúc ra mắt, hơn 270 sau sáu tháng, trên tổng 570; sau đó chững lại vì team bận tính năng. Dùng codemod của Stripe khi nó ra (tốt hơn
flowts). Thử cron tự chuyển package vừa hết bị chặn (không đủ tin cậy, bỏ) và dùng LLM đầu 2023 sửa lỗi (chưa đủ tốt). - Dùng đồ thị phụ thuộc: công cụ chấm điểm "tầm quan trọng" của mỗi package theo số package nó sẽ mở khoá; ảnh Graphviz của phần Flow còn lại. Cuối 2024 ra danh sách theo quý, đặt hạn EoL của Flow cuối Q3 2025 (lùi về cuối 2025). Cuối 2025 Webcore tự chuyển vài chục package mà team chủ không có thời gian, chấp nhận auto-suppress cho số này.
Kết quả (theo Yelp)
- Package Flow cuối cùng chuyển đầu 2/2026: 1,4 triệu dòng trong 3 năm 7 tháng; còn khoảng 6.000
@ts-expect-error(khoảng 2.000 là auto-suppress cuối cùng); type coverage 96,44% so với 83,15% với Flow. Type checking chỉ bị vỡ một lần, vài ngày. 82% engineer được khảo sát thấy năng suất tăng.
Vì sao
- Codebase chia được theo package thì chuyển dần giữ được an toàn kiểu suốt quá trình, đổi lại thời gian dài và phải có cầu nối hai chiều; tốc độ phụ thuộc vào hạn chót hơn là vào nhiệt tình (Quản lý fleet và migrate code hàng loạt, Đổi ngôn ngữ và runtime).
Bài học cho SWE
- Ấn tượng đầu của công cụ mới quyết định tốc độ tiếp nhận; dogfood trên phần nền trước khi mở rộng.
- Khi tiến độ tự nguyện chững lại, dùng đồ thị phụ thuộc để chọn thứ tự và đặt hạn theo quý.
- Phần đuôi cuối cùng thường phải do đội nền tảng tự làm.
Liên quan
#Flow sang TypeScript#Incremental migration#Monorepo package#flowts#flowgen#.d.ts sang Flow#Dogfooding#Dependency graph#EoL deadline#Type coverage
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (5)