Etsy's Journey to TypeScript
Bài tóm tắt Etsy 2021 3. Quy mô lớn Độ khó: Trung bình
Etsy · 2021 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Đối chiếu ba cách chuyển sang TypeScript: Stripe 2022 chuyển một lần bằng codemod Stripe 2022, Yelp 2026 đi từng package Yelp 2026, Etsy 2021 đi từng file, từng team, không dùng công cụ tự động.
Bối cảnh
- Etsy hơn 16 năm tuổi; monorepo có hơn 17.000 file JavaScript trải qua nhiều thế hệ site. Khó biết phần nào là thực hành tốt, phần nào là nợ kỹ thuật; JavaScript ít ràng buộc nên dùng thư viện sai dễ xảy ra. Một năm rưỡi trước bài, đội Web Platform vừa hiện đại hoá build JS (ES6).
- Vài trăm engineer, rất ít người từng viết TypeScript (kể cả tác giả).
Thay đổi chính
- Chiến lược: TypeScript strict nhất có thể, chuyển từng file (đuôi
.tsnghĩa là kiểu đáng tin,.jslà chưa); chỉ ưu tiên phần đang phát triển tích cực, không chuyển mọi file. Lý do không chuyển một lần ở chế độ strict: sẽ ra một đống lỗi bị chặn, và ai sở hữu dependency có lỗi đó cũng không rõ. - Chuẩn bị công cụ trước người: build chỉ mất 1–2 tuần (Babel
preset-typescriptbỏ kiểu,tsc --noEmitkiểm kiểu trong bộ test). Phần lâu là kiểu tốt cho mọi tiện ích, component, công cụ dùng chung, vì dependency không kiểu sẽ thànhany. - Lint cho độ cụ thể của kiểu: typescript-eslint; cấm non-null assertion và type assertion (
!,as), cho ngoại lệ bằng comment tắt lint từng dòng. - Kiểu cho API: API viết bằng PHP; tận dụng việc sinh OpenAPI spec của API công khai, viết bộ sinh spec cho mọi endpoint nội bộ, dùng
openapi-typescriptsinh kiểu, cài vào config endpoint đã sinh sẵn và wrapperEtsyFetch. Code gọi API có kiểu mà không phải sửa; đổi API gây vỡ client thì kiểm kiểu fail trước production. - Hiệu năng kiểm kiểu: editor mất gần nửa phút để hiện kiểu; kiểm toàn codebase (cả file chưa chuyển) gần 10 phút. Gặp maintainer TypeScript, dùng tính năng performance tracing mới: một kiểu vòng tròn trong tiện ích tạo object bất biến gây vòng lặp vô hạn ở file chưa chuyển. Sửa xong, một file từ gần 46 giây xuống dưới 1 giây; toàn codebase còn khoảng một phần ba thời gian, bớt khoảng 1 GB bộ nhớ.
- Rollout theo team: bắt đầu với vài team sắp mở dự án mới, hạn mềm; đội nền tảng review mọi PR, viết kiểu cho module họ cần, pair cùng. Sau đó mở cho team nào sẵn sàng: cả team học khoá ExecuteProgram trước, có talk của tác giả Effective TypeScript, huy hiệu ảo. Git commit hook chặn thay đổi TypeScript từ người ngoài safelist để không ai viết trước khi cả team sẵn sàng; làm việc trực tiếp với manager từng team (theo dõi bằng bảng tính). Nhóm "TypeScript Advisors" là người đã onboard giúp review.
- Kết quả (cuối 2021): mọi team đã onboard; từ đầu thu bắt buộc file mới viết TypeScript; khoảng 25% file có kiểu.
Vì sao
- Theo Etsy, giáo dục là quyết định đúng nhất: bật công tắc cho mọi người cùng lúc sẽ làm nghẽn đội nền tảng và chậm đội sản phẩm. Họ cố ý không dùng công cụ tự chuyển (như ts-migrate của Airbnb) vì chuyển file mình đã quen là cách học tốt, và người có ngữ cảnh chuyển tốt hơn script.
Bài học cho SWE
- Ranh giới rõ ("file
.tsthì tin được") giúp từng engineer tự cải thiện mà không phải hỏi ai. - Sinh kiểu từ nguồn sự thật sẵn có (OpenAPI của API) cho độ phủ lớn nhất với ít công sức nhất.
- Chậm của công cụ (editor, typecheck) cần được đo bằng trace như chậm của production; một kiểu xấu có thể làm chậm cả CI.
Liên quan
- Stripe 2022 · Yelp 2026 · Yelp 2026 (sinh kiểu từ schema) · Etsy 2026
- Quản lý fleet và migrate code hàng loạt · Đổi ngôn ngữ và runtime
#TypeScript#Incremental migration#Strict mode#Monorepo#typescript-eslint#OpenAPI types#Type performance tracing#Team-by-team rollout#Commit hook safelist
Được nhắc tới trong
Công ty (1)