Đọc Programming TypeScript từ chương 11 nếu bạn nhận repo Node của khách
Sách có mười ba chương, nhưng ba chương và hai phụ lục mới là phần dùng ngay ở site khách.
Tóm tắt nhanh
- Với FDE, chương 11 về tương tác với JavaScript là nơi nên mở sách đầu tiên
- Phụ lục D và F biến việc thêm kiểu cho code cũ thành các bước nhỏ, an toàn
- Chương 12 và chương 8 giúp debug dịch vụ Node chạy thật trên server của khách
Programming TypeScript của Boris Cherny có 13 chương và 7 phụ lục. Nhưng một FDE vừa được cấp quyền vào repo Node của khách không cần đọc từ trang một: chương 8, 11, 12 cùng Phụ lục D và F là phần sát nhất với việc đọc và sửa code đó.
Sách do O’Reilly xuất bản, ra mắt khoảng tháng 5/2019, phụ đề Making Your JavaScript Applications Scale. Đối tượng là lập trình viên JavaScript trình độ trung cấp. Nội dung trải từ frontend đến backend, kèm cách chuyển một dự án JavaScript có sẵn sang TypeScript và chạy nó ở production.
Mấy chữ “dự án có sẵn” mới là lý do FDE nên đọc. Ở site khách, bạn hiếm khi được làm từ đầu. Thứ bạn nhận thường là một dịch vụ Node viết bằng JavaScript thuần, vài thư viện đã cũ, và một deadline không cho phép viết lại.
Mở sách ở chương 11, không phải chương 1
Chương 11, “Interoperating with JavaScript”, dạy chuyển từ JavaScript sang TypeScript từng bước một: bắt đầu bằng việc thêm TSC, kết thúc bằng việc bật strict. Thứ tự này khớp với cách một FDE nên làm ở repo người khác.
Thử hình dung khách đưa bạn một dịch vụ Node khoảng 40 file JavaScript, và bạn cần sửa luồng xử lý webhook nằm trong ba file. Đừng chuyển cả 40 file.
Hãy thêm TSC để nó kiểm tra code hiện có, rồi chỉ chuyển ba file bạn buộc phải động vào. Diff nhỏ thì kỹ sư của khách review được, còn bạn có kiểu dữ liệu đúng ở chỗ rủi ro nhất.
Việc nên làm trong buổi đầu: chạy TSC trên repo mà chưa đổi dòng code nào. Danh sách lỗi đó là bản đồ những chỗ code đang dựa vào giả định ngầm.
Thư viện không có kiểu thì làm gì?
Phần còn lại của chương 11 xử lý thư viện JavaScript bên thứ ba theo ba trường hợp. Thư viện tự kèm khai báo kiểu thì dùng luôn. Khai báo nằm trên DefinitelyTyped thì cài thêm. Trường hợp cuối cùng, không có khai báo nào, mới là chỗ tốn thời gian.
Thử hình dung khách có một package npm nội bộ viết từ nhiều năm trước, export bằng module.exports. Không ai ngoài công ty họ từng viết type cho nó. Phụ lục D, “Recipes for Writing Declaration Files for Third-Party JavaScript Modules”, có công thức cho đúng các kiểu export CommonJS và UMD mà code Node cũ hay dùng.
Việc nên làm: xếp toàn bộ dependency vào ba nhóm trên ngay ngày đầu. Nhóm thứ ba cho biết bạn phải dành bao nhiêu giờ viết file khai báo, và đó là con số nên báo khách trước khi hứa ngày giao.
Siết kiểu theo từng cờ, không theo một cú bật
Phụ lục F, “TSC Compiler Flags for Safety”, liệt kê các cờ biên dịch giúp code an toàn hơn. Với codebase của khách, giá trị của nó nằm ở chỗ cho phép siết dần thay vì bật strict một lần rồi nhận cả trăm lỗi.
Giả sử bật một cờ làm hiện ra 120 lỗi. Một pull request sửa 120 chỗ sẽ khiến reviewer của khách ngại duyệt. Bật từng cờ, mỗi cờ một PR, mỗi PR một nhóm lỗi cùng loại, thì đội khách hiểu bạn đang làm gì và tiếp tục được sau khi bạn rời đi.
Khi lỗi nổ ra trên server của khách
Chương 12 có mục riêng “Running TypeScript on the Server”, cùng source map, project references và theo dõi lỗi. Khi dịch vụ đã biên dịch ném lỗi ở production, stack trace sẽ trỏ vào file JavaScript sinh ra. Source map đưa bạn về đúng dòng TypeScript, nhờ vậy bạn đọc được log của khách mà không phải đoán.
Chương 8 bổ sung phần còn thiếu với code Node: callback, Promise, async/await, event emitter và đa luồng an toàn kiểu bằng child process. Dịch vụ cũ của khách thường trộn callback với Promise, và gắn kiểu cho các ranh giới bất đồng bộ đó là cách nhanh nhất để thấy chỗ lỗi bị nuốt mất.
Việc nên làm: trước khi sửa bug đầu tiên, kiểm tra xem bản build của khách có sinh source map không và lỗi có được đẩy về công cụ theo dõi nào không.
Hai lỗi hay gặp khi làm ngược trình tự
Lỗi đầu tiên là bật strict ngay buổi đầu. Trình tự của chương 11 đặt strict ở cuối là có lý do: bật nó trên một repo JavaScript chưa từng có kiểu sẽ biến một việc sửa ba file thành một PR khổng lồ mà không ai bên khách muốn duyệt.
Lỗi thứ hai là đổi đuôi cả repo sang .ts trước khi xếp dependency vào ba nhóm. Thử hình dung bạn chuyển xong 40 file rồi mới phát hiện package nội bộ không có khai báo kiểu nào. Mọi chỗ gọi nó đều báo lỗi, và bạn phải dừng giữa chừng để viết file khai báo theo Phụ lục D.
Cách tránh cả hai đều nằm trong sách: phân loại thư viện trước, viết khai báo cho nhóm thứ ba, rồi mới chuyển file và bật dần từng cờ theo Phụ lục F.
Ai nên đọc, và đọc theo thứ tự nào
Sách hợp nhất với người đã viết JavaScript vững nhưng chưa từng đưa TypeScript vào một codebase có sẵn. Thứ tự gợi ý: chương 11, Phụ lục D, Phụ lục F, chương 12, rồi chương 8.
Các chương đầu về hệ thống kiểu nên mở ra khi bạn gặp khái niệm chưa rõ. Sách ra năm 2019, nên hãy đối chiếu chi tiết về công cụ và cờ biên dịch với tài liệu TypeScript hiện hành.
Đọc thôi chưa đủ. Boris Cherny có repo GitHub chính thức chứa đáp án bài tập, bcherny/programming-typescript-answers, để bạn tự làm rồi so lại. Bài tập hay hơn nữa là chuyển dần một repo Node mã nguồn mở theo đúng trình tự chương 11.
Về sự nghiệp, kỹ năng này dễ chứng minh. Một dòng CV kiểu “chuyển dần dịch vụ Node từ JavaScript sang TypeScript, bật strict qua từng PR, tự viết khai báo kiểu cho module CommonJS nội bộ” thuyết phục hơn nhiều so với “biết TypeScript”.
Thử hình dung một tin tuyển FDE ghi rằng ứng viên sẽ viết code trực tiếp trong hệ thống có sẵn của khách, với stack Node và TypeScript. Đó là tín hiệu nhà tuyển dụng cần người sửa code cũ an toàn, và dòng CV kể trên trả lời đúng yêu cầu ấy; hãy đặt nó ngay đầu phần kinh nghiệm, kèm link tới repo bạn đã tự chuyển.
Đọc mục lục bằng con mắt FDE, ba chương và hai phụ lục kể trên là phần dành cho người phải sửa code của người khác mà không làm hỏng nó.
Bài này có hữu ích không?
Cảm ơn bạn đã góp ý!