Cách Modern Web Guidance hiện đại hoá cơ sở mã của bạn và lý do bạn nên làm việc này

Hầu hết quá trình phát triển web không bắt đầu từ đầu. Điều này xảy ra trong các cơ sở mã hiện có đã tích luỹ nhiều năm giải pháp thay thế cũ, polyfill và tiện ích JavaScript (tự động định cỡ, thủ thuật tạo kiểu hộp đánh dấu tuỳ chỉnh, trình nghe scrollHeight) cho những việc mà trình duyệt hiện xử lý theo cách gốc. Nhưng vấn đề là: Mã cũ không bị hỏng. Nó hoạt động, vì vậy không ai báo cáo lỗi. Việc tái cấu trúc mã đang hoạt động (ngay cả khi mã đó đã cũ) cũng cần có sự tin tưởng, nên việc nhà phát triển ngần ngại là điều dễ hiểu.

Mặt khác, việc không tái cấu trúc mã cũ để sử dụng các tính năng web hiện đại sẽ âm thầm khiến bạn tốn kém về kích thước gói, khả năng thích ứng của trang và khả năng hỗ trợ tiếp cận. Tệ hơn nữa, khi bạn sử dụng các tác nhân lập trình trong những dự án này, chúng sẽ sao chép các quy ước năm 2015 xung quanh cùng với các mẫu lỗi thời từ dữ liệu huấn luyện.

Khi bạn xây dựng một ứng dụng mới, Modern Web Guidance sẽ hướng tác nhân của bạn đến các tính năng Baseline hiện đại. Đối với mã hiện có, Modern Web Guidance 1.0 bổ sung một quy trình hiện đại hoá giúp quét dự án của bạn để tìm các mẫu cũ và giúp tác nhân nâng cấp các mẫu đó.

Chức năng của quy trình hiện đại hoá

Khi bạn yêu cầu tác nhân hiện đại hoá một dự án (hoặc bằng cách chạy trực tiếp lệnh legacy-scan), sau đây là cách hoạt động:

  • Quét cục bộ tất định: HTML, CSS, JavaScript/TypeScript, các thành phần dành riêng cho khung và tệp package.json được quét nhanh bằng trình phân tích cú pháp Cây cú pháp trừu tượng (AST), DOM và CSS cục bộ mà không cần gọi LLM hoặc tốn chi phí mã thông báo.
  • Danh mục quy tắc cũ: Trình quét gắn cờ quá nhiều nội dung trong mỗi lần chạy sẽ bị bỏ qua. Chúng tôi đã thử nghiệm các quy tắc đề xuất trên khoảng 45.000 kho lưu trữ nguồn mở được chia làm đôi: Các quy tắc được viết và điều chỉnh trên nửa viết quy tắc, đồng thời được chấm điểm trên nửa còn lại chưa từng thấy. Chúng tôi đã loại bỏ nhiều quy tắc đề xuất hơn là giữ lại, bỏ qua các tính năng không có mã tương đương trong hệ thống cũ và loại bỏ các thay đổi chỉ mang tính cú pháp mà không mang lại lợi ích thực sự (chẳng hạn như viết lại các bộ chọn đồng cấp + hoặc ~ đang hoạt động thành :has()). Để được áp dụng theo mặc định, một quy tắc phải đạt độ chính xác của trình so khớp tĩnh ít nhất 80% và độ chính xác sau khi xác minh ít nhất 90% trên mã chưa từng thấy.
  • Lọc kết quả dương tính giả dựa trên bối cảnh: Mỗi kết quả khớp với quy tắc đều đi kèm với các tiêu chí keepWhen/dropWhen rõ ràng. Điều này yêu cầu tác nhân đánh giá mã xung quanh và loại bỏ các phương án dự phòng có chủ ý, các biện pháp bảo vệ CSS @supports hoặc các mã tương tự trước khi trình bày kết quả.
  • Phạm vi áp dụng cho các mẫu cũ có độ tin cậy cao (và ngày càng tăng): legacy-scan kiểm tra một nhóm nhỏ trong số khoảng 200 hướng dẫn của chúng tôi (khoảng 20%) nơi mã cũ có thể được phát hiện một cách tất định mà không có kết quả dương tính giả và chúng tôi đang mở rộng phạm vi áp dụng đó theo thời gian. Đối với phần còn lại của danh mục, tác nhân của bạn sẽ tìm kiếm và truy xuất các hướng dẫn khi bạn xây dựng.

Cách gọi quy trình hiện đại hoá

Để hiện đại hoá mã bằng Modern Web Guidance, bạn cần có phiên bản 1.0 trở lên. Cài đặt hoặc cập nhật bằng npm hoặc trang bổ trợ của tác nhân:

# Install Modern Web Guidance 1.0 in your project
npx modern-web-guidance@latest install

# Or update an existing installation
npx modern-web-guidance@latest update

Vì quy trình hiện đại hoá là một phần của định nghĩa kỹ năng cốt lõi, nên bạn có thể kích hoạt trình quét bằng ngôn ngữ tự nhiên bằng cách yêu cầu tác nhân kiểm tra "mẫu cũ" hoặc "hiện đại hoá" trên một kho lưu trữ hoặc thư mục.

Lưu ý: Việc đặt tên cho một thành phần sẽ thực hiện tra cứu hướng dẫn thông thường.

Để minh hoạ, sau đây là một câu lệnh mẫu để quét toàn bộ kho lưu trữ:

Modernize this repository using Modern Web Guidance. Scan our frontend files for legacy patterns, verify the findings, and propose a modernization plan before making any code edits.

Bạn cũng có thể trỏ đến một thư mục cụ thể:

Check src/components/forms for legacy web patterns that can be refactored to modern Baseline features.

Mặc dù hiện tại bạn có thể chạy legacy-scan theo cách thủ công trong thiết bị đầu cuối, nhưng các tính năng tích hợp quy trình CI/CD tự động vẫn đang trong quá trình phát triển.

Ví dụ về các mẫu mà công cụ này phát hiện và khắc phục

Các quy tắc đủ điều kiện nhắm đến các mẫu phản thiết kế cũ phổ biến trên 4 miền: Biểu mẫu và giao diện người dùng, hộp thoại và chế độ điều khiển, bố cục CSS, kiểu chữ và thiết kế hình ảnh, và Bảo mật. Sau đây là bảng các mẫu cũ và mẫu hiện đại thay thế:

Miền Đã phát hiện mẫu cũ Thay thế hiện đại
Biểu mẫu và giao diện người dùng Điểm nối tự động đổi kích thước vùng văn bản scrollHeight JS CSS field-sizing: content (form-fields-automatically-fit-contents)
Biểu mẫu và giao diện người dùng Nhập trình xử lý gửi keydown thiếu trình bảo vệ IME if (e.isComposing || e.keyCode === 229) return; (ime-safe-enter-submit)
Biểu mẫu và giao diện người dùng Kiểu CSS :invalid sớm tạo kiểu cho các dữ liệu đầu vào chưa được xử lý khi tải Lớp giả :user-invalid và :user-valid (validate-input-after-interaction)
Biểu mẫu và giao diện người dùng Thiếu mã thông báo autocomplete trên biểu mẫu xác thực và thanh toán Giá trị autocomplete được chuẩn hoá (autofill-sign-in-form, autofill-payment-form)
Hộp thoại và nút điều khiển e.target === dialog trình theo dõi lượt nhấp làm hỏng tính năng kéo để chọn <dialog closedby="any"> có tính năng cải tiến tăng dần (hộp thoại)
Hộp thoại và nút điều khiển Trình theo dõi lượt nhấp addEventListener bắt buộc cho lớp phủ Thuộc tính popover và popovertarget khai báo (declarative-dialog-popover-control)
Bố cục CSS, kiểu chữ và thiết kế hình ảnh max-height: 9999px thủ thuật tạo ảnh động cho thành phần accordion interpolate-size: allow-keywords và calc-size() (animate-to-intrinsic-sizes)
Bố cục CSS, kiểu chữ và thiết kế hình ảnh Chuyển đổi lớp mẹ JS dựa trên trạng thái con Bộ chọn :has(:checked) / :has(:focus-visible) quan hệ (child-state-based-styling)
Bố cục CSS, kiểu chữ và thiết kế hình ảnh @media (prefers-color-scheme: dark) khối trùng lặp Hàm CSS light-dark() (dark-mode, dark-mode-toggle)
Bảo mật Thẻ tập lệnh CDN bên ngoài thiếu tính năng Kiểm tra tính toàn vẹn của tài nguyên phụ Thuộc tính integrity và crossorigin="anonymous" (secure-external-subresources)

Ví dụ về việc biến đổi mã

Khi được nhắc, tác nhân lập trình có thể chuyển đổi các mẫu phản thiết kế cũ thành mẫu hiện đại bằng quy trình hiện đại hoá. Dưới đây là một số ví dụ:

Phần tử <textarea> tự động tăng kích thước

JavaScript cũ đo lường scrollHeight trên mỗi sự kiện input buộc bố cục phải bị xáo trộn. Điều này có thể gây ra các vấn đề về hiệu suất, cụ thể là với Lượt tương tác đến nội dung hiển thị tiếp theo (INP). Bằng cách sử dụng quy trình hiện đại hoá, tác nhân của bạn có thể khắc phục vấn đề này:

// Before: Imperative layout recalculation on every keystroke
textarea.addEventListener('input', () => {
  textarea.style.height = 'auto';
  textarea.style.height = `${textarea.scrollHeight}px`;
});

Bạn không cần JavaScript cho việc này. Quy trình hiện đại hoá sẽ hướng dẫn tác nhân thay thế bằng CSS:

/* After: Native declarative field sizing */
textarea {
  field-sizing: content;
  min-block-size: 3lh;
  max-block-size: 15lh;
}

Cửa sổ bật lên mang tính khai báo

Bạn có thể thay thế logic cửa sổ bật lên và phương thức tuỳ chỉnh bằng trình nghe sự kiện JavaScript bằng các thuộc tính HTML chuẩn:

<!-- Before: a click listener that only calls showPopover() -->
<button id="openBtn">Open Menu</button>
<div id="menu" popover>Menu Content</div>
<script>
  openBtn.addEventListener('click', () => menu.showPopover());
</script>

<!-- After: declarative control, no JavaScript -->
<button popovertarget="menu">Open Menu</button>
<div id="menu" popover>Menu Content</div>

Gửi nội dung nhập an toàn cho IME

Trình nghe phím Enter không được bảo vệ sẽ kích hoạt việc gửi tin nhắn sớm khi người dùng nhập bằng Trình chỉnh sửa phương thức nhập (IME) tiếng Nhật, tiếng Trung hoặc tiếng Hàn.

Tác nhân của bạn thêm các biện pháp bảo vệ trạng thái của thành phần kết hợp:

// Before: Fires mid-composition when confirming kanji/hanzi characters
textarea.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault();
    sendMessage();
  }
});


// After: Accurately checks IME composition state
textarea.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault();
    if (e.isComposing || e.keyCode === 229) return;
    sendMessage();
  }
});

Cách hoạt động: Quy trình hiện đại hoá gồm 4 bước

Việc tái cấu trúc mã đang hoạt động trong một ứng dụng hiện có cần có sự tin tưởng, vì không ai muốn tỷ lệ rời bỏ tự động hoặc hồi quy tinh vi. Đó cũng là lý do tại sao không có cờ --fix: Ngay cả những hoạt động hiện đại hoá có vẻ đơn giản cũng thường trở thành hoạt động tái cấu trúc nhiều lớp (chẳng hạn như xoá trình nghe JS bắt buộc hoặc gói npm và chuyển hành vi sang HTML và CSS) với hành vi tinh tế và thách thức về khả năng hỗ trợ của trình duyệt.

Thay vào đó, quy trình hiện đại hoá sẽ chạy một vòng lặp gồm 4 bước với tác nhân lập trình của bạn:

  1. Quét (legacy-scan): Tác nhân chạy npx modern-web-guidance legacy-scan <path> --json, giúp sàng lọc trước các tệp để tìm chuỗi con có liên quan, nhờ đó chỉ khởi động trình phân tích cú pháp AST, CSS và HTML trên các tệp và quy tắc đề xuất. Nếu một kết quả đạt đến mức này, thì khả năng cao (khoảng 92%) là kết quả đó không phải là kết quả dương tính giả. Mỗi trận đấu đều có một danh sách kiểm tra xác minh cho nhân viên hỗ trợ.
  2. Xác minh theo bối cảnh (keepWhen/dropWhen): Vì tác nhân lập trình đã mở kho lưu trữ, nên tác nhân này sẽ kiểm tra mã xung quanh mỗi kết quả trùng khớp theo tiêu chí xác minh của quy tắc đó. Nếu một lệnh đọc scrollHeight là một phần của thao tác cuộn ảo thay vì thủ thuật <textarea>, hoặc nếu một lệnh kiểm tra @supports đã bảo vệ thuộc tính, thì kết quả tìm được sẽ bị loại bỏ mà không có thông báo.
  3. Báo cáo: Tác nhân tóm tắt các kết quả đã xác minh (lưu ý rằng legacy-scan bao gồm một nhóm nhỏ các hướng dẫn có quy tắc tất định, cộng với kế hoạch hiện đại hoá nếu bạn yêu cầu xem xét kế hoạch trước khi chỉnh sửa).
  4. Truy xuất hướng dẫn, tái cấu trúc và xác minh kiểm thử: Khi được yêu cầu hiện đại hoá, tác nhân sẽ chạy npx modern-web-guidance retrieve <guide-id> để tìm nạp hướng dẫn thích hợp. Công cụ này thực thi việc tái cấu trúc mã theo các mẫu tương thích của Baseline trong hướng dẫn, đồng thời chạy lại legacy-scan <path> trên các tệp đã sửa đổi cùng với bộ kiểm thử của dự án để xác nhận việc giải quyết.

Dùng thử

Dù là chạy một legacy-scan một lần trong dòng lệnh hay yêu cầu tác nhân lập trình hiện đại hoá một mô-đun cũ, quy trình hiện đại hoá đều giúp bạn giải quyết nợ kỹ thuật của nền tảng web cũ mà không gặp phải sự phiền toái của các công cụ tìm lỗi mã nguồn truyền thống.

Kết hợp Modern Web Guidance với Chrome DevTools cho tác nhân khi bạn muốn chuyển từ việc hiện đại hoá mã tĩnh sang xác minh, đo điểm chuẩn và gỡ lỗi trình duyệt trực tiếp.

Các bước tiếp theo và tài nguyên