Cẩm nang · Nền tảng token và đa nền tảng

Chuyển sang design system mới mà không phải làm lại từ đầu

Migration thành công không phải viết lại toàn bộ, mà là tiếp quản dần dần từ lớp token cho đến từng component.

Chốt nhanh

Anh Chị không cần dừng sản phẩm hay viết lại toàn bộ để chuyển sang design system mới. Cách làm đúng là cắm hệ token mới vào codebase cũ trước, sau đó thay thế component từng màn hình theo thứ tự ưu tiên kinh doanh. Sản phẩm vẫn chạy liên tục, đội kỹ thuật quen dần với hệ mới, và rủi ro hồi quy được kiểm soát từng bước.

Migration thành công hay thất bại thường được quyết định ngay từ tuần đầu tiên, trước khi viết một dòng component mới nào. Đội kỹ thuật nào bỏ qua bước audit và nhảy thẳng vào xây hệ mới thường sẽ phát hiện ra giữa chừng rằng codebase cũ có nhiều biến thể ngoài dự kiến, và toàn bộ thiết kế phải điều chỉnh lại. Sinh Vũ chia sẻ cách tiếp cận dưới đây để Anh Chị tránh đúng vết đó.

Bắt đầu từ audit, không phải từ thiết kế

Trước khi xây bất cứ component nào mới, cần biết codebase cũ đang có gì. Audit giao diện cũ không phải công việc của designer mà là công việc chung của designer và kỹ thuật. Mục tiêu là phân loại mỗi pattern hiện có vào một trong ba nhóm:

  • Giữ nguyên: đang hoạt động tốt, không cần đụng vào trong giai đoạn đầu.
  • Refactor: cấu trúc còn dùng được nhưng cần điều chỉnh để nhận token mới.
  • Thay mới: cần xây lại từ đầu theo hệ mới vì cấu trúc cũ không tương thích.

Audit còn giúp phát hiện sớm các vấn đề kỹ thuật có thể chặn migration: CSS viết kiểu global (áp cho toàn trang thay vì từng component), inline style (style viết thẳng vào thẻ HTML), thư viện bên thứ ba có xung đột về độ ưu tiên CSS. Mỗi loại này cần xử lý riêng trước khi nhúng component mới vào.

Cắm token vào trước, component đến sau

Token (các biến giá trị thiết kế như màu sắc, khoảng cách, cỡ chữ) có thể được khai báo dưới dạng CSS custom properties và áp vào codebase cũ mà không cần thay một component nào. Đây là bước đầu tiên và thường là bước nhanh nhất trong toàn bộ quá trình migration.

Khi token đã vào codebase, đội kỹ thuật có thể bắt đầu tham chiếu các giá trị đó ngay trong code cũ, làm quen với cách hệ token vận hành, và bắt đầu thấy sự thay đổi thực tế trên giao diện. Việc này rút ngắn khoảng cách giữa thời điểm bắt đầu dự án và thời điểm đội khách thấy kết quả đầu tiên.

Trong thực hành tại Sinh Vũ, token layer thường được giao trong hai đến ba tuần đầu của dự án, trước khi component library hoàn thiện, để đội kỹ thuật không cần ngồi chờ.

Thay component theo giá trị kinh doanh, không theo độ dễ kỹ thuật

Sau khi token đã vào, bước tiếp theo là thay thế component cũ bằng component mới theo thứ tự ưu tiên. Lỗi phổ biến nhất ở giai đoạn này là chọn màn hình dễ làm trước vì muốn có kết quả nhanh, trong khi những màn hình quan trọng nhất với khách hàng vẫn còn nguyên hệ cũ.

Thứ tự đúng là ưu tiên theo giá trị kinh doanh: màn hình nhiều lượt truy cập, màn hình chuyển đổi cao (trang đặt hàng, trang đăng ký), hoặc màn hình mà đội sales dùng để demo. Khi những màn hình này được migrate trước, Anh Chị thấy giá trị thực tế sớm hơn và có cơ sở để quyết định có nên tiếp tục không.

Dùng Strangler Fig để hệ cũ và mới cùng tồn tại

Big bang rewrite (viết lại toàn bộ cùng lúc): Dừng mọi phát triển, xây lại toàn bộ hệ mới, rồi chuyển một lần. Rủi ro cao, thường kéo dài gấp đôi dự kiến, khó rollback khi có sự cố. Strangler Fig (thay thế dần): Component mới và cũ cùng tồn tại trong codebase, từng phần được thay thế theo sprint. Sản phẩm vẫn chạy, có thể rollback từng phần, đội quen dần với hệ mới trước khi toàn bộ chuyển xong.

Strangler Fig là khung tư duy do Martin Fowler đặt tên, lấy từ hình ảnh cây leo dần bao phủ và thay thế cây chủ. Áp vào migration design system: xây component mới song song, để chúng thay thế dần component cũ theo từng màn hình, cho đến khi hệ cũ không còn được tham chiếu nữa thì xóa đi. Không cần một ngày cắt chuyển dứt khoát.

Để làm được điều này an toàn, cần có feature flag (cờ bật tắt tính năng) cho phép toggle giữa UI cũ và mới mà không cần deploy lại. Đây là lưới an toàn quan trọng nhất trong toàn bộ quá trình.

Những lỗi thường gặp cần tránh

  • Không audit trước: Xây component mới rồi mới phát hiện codebase cũ có quá nhiều biến thể không tính đến, phải điều chỉnh lại thiết kế giữa chừng.
  • CSS specificity conflict: Khi CSS cũ viết theo kiểu global và có độ ưu tiên cao, component mới bị ghi đè không mong muốn, giao diện hiển thị sai mà không rõ nguyên nhân.
  • Không có feature flag: Khi phát hiện bug trên UI mới, không có cách rollback nhanh mà không ảnh hưởng toàn bộ người dùng.
  • Bỏ qua accessibility: Hệ mới trông đẹp hơn nhưng các tiêu chuẩn tiếp cận (accessibility) bị bỏ sót. Cần audit a11y riêng song song với migration giao diện.

Không thể xây component mới phù hợp nếu không biết bao nhiêu biến thể của cùng một pattern đang tồn tại trong codebase cũ.

Quan điểm ngành, được chia sẻ bởi nhiều đội migration lớn

Nguồn tham khảo

Martin Fowler: Strangler Fig Application (martinfowler.com). Quan điểm ngành về design system migration. Sinh Vũ: kinh nghiệm thực hành dự án A3.

Câu hỏi thường gặp

Chúng tôi có bắt buộc phải dừng phát triển tính năng mới trong thời gian migration không?

Không bắt buộc, nhưng cần phân kỳ rõ ràng. Migration chạy song song với phát triển tính năng mới là hoàn toàn khả thi nếu Anh Chị tách biệt phạm vi: tính năng mới xây theo component mới ngay, tính năng cũ được migrate dần theo sprint. Rủi ro lớn nhất là đội vừa build vừa migrate cùng một màn hình cùng lúc, lúc đó conflict sẽ nhiều.

Token mới có áp được vào codebase cũ không nếu chúng tôi đang dùng inline style hoặc style viết thẳng vào file JS?

Áp được, nhưng cần thêm một bước cách ly. CSS custom properties (biến CSS do trình duyệt hỗ trợ sẵn) có thể khai báo ở lớp ngoài cùng và ghi đè nhiều kiểu style bên trong. Với inline style hoặc style-in-JS, Anh Chị cần refactor từng component để đọc giá trị từ token thay vì hardcode. Đây là lý do audit kỹ thuật trước migration rất quan trọng.

← Về Hệ thiết kế số
{INJ}