[{"data":1,"prerenderedAt":135},["ShallowReactive",2],{"list-\u002Fprojects-vi":3},[4,80],{"entry":5,"writtenIn":78,"onlyIn":79},{"id":6,"title":7,"body":8,"date":60,"description":61,"extension":62,"meta":63,"navigation":64,"path":65,"role":66,"seo":67,"stack":68,"stem":72,"tags":73,"year":76,"__hash__":77},"content_vi\u002Fprojects\u002Ftypescript-migration.md","TypeScript trong một codebase SAPUI5",{"type":9,"value":10,"toc":51},"minimark",[11,16,20,24,27,31,34,37,41,44,48],[12,13,15],"h2",{"id":14},"bối-cảnh","Bối cảnh",[17,18,19],"p",{},"Một ứng dụng SAPUI5 nội bộ, đội logistics dùng mỗi ngày. Khoảng bốn mươi controller, sáu năm lịch sử, ba người bảo trì. Mọi màn hình đều viết bằng JavaScript thuần trên hệ module của UI5.",[12,21,23],{"id":22},"vấn-đề","Vấn đề",[17,25,26],{},"Lỗi lọt ra production hầu như không bao giờ là lỗi logic. Chúng là lỗi hình dạng dữ liệu: một trường bị đổi tên trên service OData, một đường model không còn phân giải được, một controller đọc thuộc tính mà entity set đã thôi trả về. Không có gì lộ ra cho tới khi ai đó mở đúng màn hình.",[12,28,30],{"id":29},"cách-giải","Cách giải",[17,32,33],{},"Việc chuyển đổi chạy theo từng thư mục, tính năng vẫn phát triển song song. Định nghĩa kiểu được sinh từ metadata của service thay vì viết tay, nhờ vậy hợp đồng OData vẫn là nguồn sự thật duy nhất. Controller chỉ được chuyển khi đang phải sửa vì lý do khác, nên diff của mỗi pull request vẫn đọc được.",[17,35,36],{},"Build giữ nguyên bộ tooling UI5 sẵn có. Thêm một bundler thứ hai đồng nghĩa với việc phải nuôi hai đường build suốt thời gian chuyển đổi.",[12,38,40],{"id":39},"kết-quả","Kết quả",[17,42,43],{},"Không có số đo đối chiếu — trước khi chuyển không hề có hệ thống theo dõi lỗi, nên mọi con số trước\u002Fsau đều là bịa. Thứ quan sát được: đổi tên trên service giờ làm hỏng bản build thay vì hỏng một màn hình, và ba lỗi hình dạng dữ liệu tìm thấy trong lúc chuyển đổi đều đang sống trên production.",[12,45,47],{"id":46},"bài-học","Bài học",[17,49,50],{},"Việc sinh kiểu từ metadata của service quan trọng hơn bản thân cuộc chuyển đổi. Interface viết tay sẽ lệch khỏi backend chỉ sau một bản phát hành, mà một kiểu dữ liệu nói dối thì tệ hơn là không có kiểu nào.",{"title":52,"searchDepth":53,"depth":53,"links":54},"",2,[55,56,57,58,59],{"id":14,"depth":53,"text":15},{"id":22,"depth":53,"text":23},{"id":29,"depth":53,"text":30},{"id":39,"depth":53,"text":40},{"id":46,"depth":53,"text":47},"2026-05-12","Chuyển dần một ứng dụng SAPUI5 lớn sang TypeScript mà không phải dừng việc phát triển tính năng.","md",{},true,"\u002Fprojects\u002Ftypescript-migration","Kỹ sư frontend",{"title":7,"description":61},[69,70,71],"SAPUI5","TYPESCRIPT","NODE","projects\u002Ftypescript-migration",[74,75],"sapui5","typescript","2025 — 2026","N0mhwfIKBDG-rJqc_-R0iinAQoON1Gai96ivs1yyW80","vi",null,{"entry":81,"writtenIn":78,"onlyIn":79},{"id":82,"title":83,"body":84,"date":121,"description":122,"extension":62,"meta":123,"navigation":64,"path":124,"role":125,"seo":126,"stack":127,"stem":129,"tags":130,"year":133,"__hash__":134},"content_vi\u002Fprojects\u002Fwarehouse-console.md","Bảng điều khiển kho",{"type":9,"value":85,"toc":114},[86,88,91,93,96,98,101,104,106,109,111],[12,87,15],{"id":14},[17,89,90],{},"Người vận hành kho xử lý hàng nhập. Công việc lặp lại có chủ đích: quét, kiểm, xác nhận, sang lô kế tiếp. Trước đây mỗi lượt như vậy phải đi qua bốn màn hình riêng, và cùng một mã định danh phải gõ lại ở ba trong số đó.",[12,92,23],{"id":22},[17,94,95],{},"Giao diện được thiết kế như thể mỗi màn hình là một điểm đến. Thực tế thì không ai điều hướng trong công cụ mình dùng cả ngày — họ nhớ vị trí và thôi đọc nhãn ngay sau tuần đầu. Bốn điểm đến nghĩa là bốn bộ vị trí phải nhớ, và việc gõ lại chính là chỗ lỗi chui vào.",[12,97,30],{"id":29},[17,99,100],{},"Bốn màn hình gộp thành một bảng điều khiển với bố cục cố định: ô quét luôn ở cùng một chỗ, mục đang xử lý ở giữa, lịch sử ở cạnh bên. Không gì dịch chuyển giữa các trạng thái, vì một control đổi vị trí là một control phải đi tìm lại.",[17,102,103],{},"Ưu tiên bàn phím. Mọi thao tác làm được mà không cần chuột, vì người vận hành đeo găng và dùng máy quét cầm tay phát ra tín hiệu phím.",[12,105,40],{"id":39},[17,107,108],{},"Không đo chính thức — trước khi đổi, đội không có dữ liệu thời gian, và số lượt mỗi ca dao động quá nhiều theo lượng hàng nhập nên so sánh theo tháng là vô nghĩa. Thứ người vận hành phản hồi: hết phải gõ lại, và đào tạo người mới giờ chỉ còn một màn hình thay vì bốn.",[12,110,47],{"id":46},[17,112,113],{},"Cái lợi đến từ việc bỏ bớt điều hướng, không phải từ việc vẽ lại từng màn hình. Nếu bắt đầu bằng một đợt làm mới giao diện cho cả bốn màn hình thì việc gõ lại đã sống sót qua đó.",{"title":52,"searchDepth":53,"depth":53,"links":115},[116,117,118,119,120],{"id":14,"depth":53,"text":15},{"id":22,"depth":53,"text":23},{"id":29,"depth":53,"text":30},{"id":39,"depth":53,"text":40},{"id":46,"depth":53,"text":47},"2026-02-03","Một màn hình thay cho bốn, làm cho người vận hành ngồi cùng một giao diện suốt tám tiếng mỗi ngày.",{},"\u002Fprojects\u002Fwarehouse-console","Thiết kế và frontend",{"title":83,"description":122},[69,70,128],"DOCKER","projects\u002Fwarehouse-console",[74,131,132],"enterprise","ux","2024 — 2025","OuEsfVUY9AprfOZM6FgegpUIm3Y_qtSHH03vgVHe6fI",1788956392287]