Tin tức

Cloudflare viết lại module registry của Workers để tương thích với Node.js

Cloudflare đã xây dựng lại module registry trong workerd, runtime Workers của họ, để nhanh hơn, tuân thủ tiêu chuẩn tốt hơn và gần gũi hơn với Node.js. Việc triển khai mới xử lý các specifier module như URL, hỗ trợ các API import.meta, và cho phép biên dịch lười và chia sẻ bộ nhớ cache.

September 9, 2026· 4 min read· Nguồn: Cloudflare Blog
Cloudflare viết lại module registry của Workers để tương thích với Node.js

Cloudflare đã viết lại module registry trong workerd, lõi mã nguồn mở của runtime Workers, để nhanh hơn, tuân thủ tiêu chuẩn tốt hơn và gần gũi hơn với Node.js. Việc triển khai mới, có sẵn qua cờ tương thích new_module_registry, thay đổi cách các module được phân giải, tải và lưu vào bộ nhớ cache.

Tại sao cần registry mới?

Registry cũ phân giải các specifier module như đường dẫn kiểu hệ thống tệp, không phải URL. Điều đó khiến việc triển khai import.meta.url trở nên khó khăn, và các import tương đối không tuân theo cùng quy tắc như new URL(). Các giao thức như node:cloudflare: được xử lý như các tiền tố chuỗi đặc biệt thay vì các giao thức thực sự.

Registry cũ cũng biên dịch toàn bộ bundle Worker ngay từ đầu, ngay cả khi một số module không bao giờ được import, và giữ một bản sao riêng của mọi thứ cho mỗi isolate V8. Vì Cloudflare chạy nhiều isolate V8 của cùng một Worker để phân tải, điều đó có nghĩa là biên dịch cùng một mã nguồn nhiều lần và giữ nhiều bản sao trong bộ nhớ.

Registry mới bắt đầu từ URL làm định dạng specifier và coi sự lười biếng và chia sẻ bộ nhớ cache là các mục tiêu thiết kế ngay từ ngày đầu. Registry hiện tại sẽ không biến mất—các Worker đã triển khai sẽ tiếp tục hoạt động như trước.

Những gì thay đổi với cờ mới

Bật new_module_registry mang lại một số cải tiến:

  • import.meta.url, import.meta.mainimport.meta.resolve() đều hoạt động.
  • Các specifier module được phân tích cú pháp và phân giải như URL thực sự, bao gồm cả chuỗi truy vấn và fragment.
  • Các built-in node: phân giải đến cùng một instance module bất kể bạn truy cập chúng bằng cách nào.
  • Các thuộc tính import (with { type: 'json' }) được xác thực chính xác.
  • require() trên một module ES tuân theo quy tắc require(esm) của Node.js.
  • Các lỗi sử dụng các lớp và thông điệp nhất quán bất kể đường dẫn tải nào kích hoạt chúng.
  • Các module biên dịch lười khi được import lần đầu.
  • Các module WebAssembly hỗ trợ import pha nguồn.

import.meta trong hành động

Với registry mới, import.meta.url cung cấp cho bạn URL của module và import.meta.main chỉ đúng cho module điểm vào. import.meta.resolve() phân giải một specifier so với module hiện tại mà không import nó—đây là một phép biến đổi chuỗi thuần túy, giống như trong Node.js và trình duyệt.

Một chi tiết: import.meta.resolve() chuẩn hóa mã hóa phần trăm như new URL(), vì vậy nó thu gọn các đường dẫn như ./a/../b.js, nhưng không giải mã các ký tự đã được mã hóa phần trăm.

Điều này có nghĩa gì cho các bundler

Registry mới mở ra cánh cửa cho các bundler như Rolldown (được sử dụng bởi Vite 8) để thực hiện ít phép biến đổi hơn và dựa nhiều hơn vào runtime để phân giải module. Khi bạn import một API Node.js trong Worker, bạn đang import một module được tích hợp trong workerd, không phải một polyfill được đóng gói vào mã của bạn. Các module Wasm, text và binary được cung cấp dưới dạng các tệp riêng biệt, được tham chiếu bằng specifier thay vì được nội tuyến.

Nếu bạn triển khai với --no-bundle hoặc tải lên nhiều module trực tiếp, toàn bộ đồ thị module sẽ hiển thị tại runtime chính xác như được viết. Trong mọi trường hợp, công việc của module registry là lấy một specifier, xác định mã nó trỏ đến, biên dịch nó và chuyển cho V8 một đối tượng module mà nó có thể liên kết và chạy.

Registry mới bắt đầu từ URL làm định dạng specifier và coi sự lười biếng và chia sẻ bộ nhớ cache là những thứ cần thiết kế ngay từ ngày đầu.
Ban biên tập Manul X