· kaynak Cloudflare blog
Cloudflare, workerd modül kayıt defterini Node.js tarzı modül çözümlemesi için yeniden yazdı
Cloudflare, workerd içindeki modül kayıt defterini yeniden yazdı; böylece Workers modülleri gerçek URL'ler olarak çözümlüyor, import.meta desteği kazanıyor, geç derleme yapıyor ve cache'leri isolate'ler arasında paylaşıyor — yeni new_module_registry flag'i ile kullanılabilir.

Cloudflare neyi yeniden inşa etti
Cloudflare, Workers runtime'ını çalıştıran açık kaynak motoru workerd içindeki modül kayıt defterini (module registry) yeniden yazdı; böylece modül çözümleme, yükleme ve önbellekleme artık Node.js gibi yapılıyor. Cloudflare bloguna göre yeni uygulama daha hızlı, web standartlarını daha yakından takip ediyor ve şu anda bir opt-in anahtarıyla kullanılabilir: bir Worker'ın compatibility_flags listesine new_module_registry eklemek etkinleştirir. Mevcut dağıtımlar güncel kayıt defterinde devam ediyor; Cloudflare, bunun yerinde kaldığını belirtiyor.
Yeniden yazım, daha geniş bir uyumluluk çabasının zirvesi. Cloudflare'ye göre Workers runtime'ı artık serverless bağlamda anlamlı olan tüm stabil Node.js API'lerini kapsıyor, bu API'ler varsayılan olarak açık ve sıkıştırılmış bundle boyutu sınırı kaldırıldığından 64 MiB'e kadar Node.js uygulamaları tüm planlarda dağıtılabiliyor.
Cloudflare'ye göre yalnızca API yüzeyi yeterli değildi, çünkü Node.js programları aynı zamanda bir runtime'ın ESM, CommonJS ve WebAssembly modüllerini nasıl çözdüğüne ve önbelleğe aldığına da bağlı — tam olarak modül kayıt defterinin sorumlulukları.
Flag neyi açıyor
new_module_registry'nin etkinleştirilmesi bir dizi davranışsal düzeltme getiriyor. import.meta.url, import.meta.main ve import.meta.resolve() artık çalışıyor. Modül belirteçleri (specifier) gerçek URL'ler olarak ayrıştırılıp çözümleniyor — query string ve fragment'lar dahil — ve node: yerleşik modülleri nasıl referans verilirse verilsin tek bir modül örneğine denk geliyor. { type: '' } gibi import attribute'lar düzgün doğrulanıyor, bir ES modülüne karşı require() Node.js'in require(esm) kurallarını izliyor ve hangi yoldan yüklenirse yüklensin hatalar tutarlı sınıflar ve mesajlarla fırlatılıyor. Modüller ilk kez içe aktarıldıklarında — statik veya dinamik — geç olarak derleniyor ve WebAssembly modülleri source-phase import desteği kazanıyor.
Bundler'lar artık daha az iş yapabilir
Bugün Workers kodlarının çoğu önceden bundle edilmiş olarak geliyor. Cloudflare, Wrangler'ın bir uygulamayı ve bağımlılıklarını tek bir modül betiğine katlamak için esbuild çalıştırdığını, import'ları sıradan fonksiyon çağrılarıyla değiştirdiğini açıklıyor — şirket, bunların yüz binlerce satıra büyüdüğünü gördüğünü belirtiyor. Cloudflare Vite eklentisi farklı bir yol izliyor: Vite 8 ile birlikte bundle etmeyi Rolldown üstleniyor; import'ları çözümlüyor, gerektiğinde CommonJS'i ESM'e dönüştürüyor ve bir giriş modülü ile code splitting'in ürettiği chunk'ları çıkarıyor.
Bu modelde Node.js API'leri polyfill değil; workerd'ye gömülü durumda ve Wasm, metin ile ikili modüller belirteçle referans verilen ayrı dosyalar olarak yükleniyor. --no-bundle ile dağıtım, tam modül grafiğini yazıldığı haliyle runtime'a gönderiyor. Cloudflare'ye göre yeni kayıt defteri, Rolldown gibi bundler'ların daha az dönüşüm uygulamasını ve modül çözümlemeyi runtime'a devretmesini mümkün kılıyor.
Eski kayıt defteri neden engeldi
Önceki uygulama belirteçleri URL değil dosya sistemi tarzı yollar olarak çözümlüyordu. Cloudflare'ye göre bu küçük görünen ayrım import.meta.url'yi imkânsız kılıyor, göreli import'ların new URL()'den farklı kurallar izlemesine yol açıyor ve node: ile cloudflare:'nin gerçek protokoller yerine özel string önekleri olarak ele alınmasını zorunlu kılıyordu. Ayrıca her modül kullanılıp kullanılmadığına bakılmaksızın tüm Worker bundle'ını önceden derliyor ve her V8 isolate içinde her şeyin özel bir kopyasını tutuyordu — bu ciddi bir maliyet, çünkü Cloudflare yükü dağıtmak için aynı Worker'ın birkaç V8 isolate'ini CPU çekirdekleri arasında çalıştırıyor; yani aynı kaynak kodu tekrar tekrar derleniyor ve bellekte tutuluyordu. Bunların hiçbiri bug sayılmıyordu ama uygulamayı breaking change'ler olmadan geliştirmeyi zorlaştırıyordu; yeni kayıt defteri URL'lerden başlıyor ve geç derleme ile cache paylaşımını tasarım temelleri olarak ele alıyor.
Cloudflare ayrıca workerd deposuna, yeni kayıt defterinin V8'in modül API'leriyle nasıl etkileşime girdiğini kapsayan referans dokümantasyonu ekledi.
Pratikte URL semantiği
Bilinmesi gereken birkaç davranış var. import.meta.main yalnızca Worker'ın giriş noktası olarak yapılandırılmış modül için true; diğer tüm modüller false alıyor. import.meta.resolve() Node.js ve tarayıcılardaki gibi saf bir string işlemi: hedef modülün var olup olmadığını doğrulamıyor, hiç URL olarak ayrıştırılamayan belirteçler için TypeError fırlatıyor ve percent-encoding'i new URL() gibi normalize ediyor — nokta segmentlerini daraltırken zaten kodlanmış karakterleri çözmüyor. Belirteçler artık URL olduğundan, aynı kaynağa işaret eden farklı query string veya fragment'lar farklı modül örnekleri olarak ele alınıyor; bu, tarayıcıların kullandığı modül kimliği kurallarını yansıtıyor.
Neden önemli
Workers geliştiricileri için bu, kodun veya bağımlılıkların Workers üzerinde basitçe bozulduğu bir hata kategorisini kapatıyor — import.meta.resolve() daha önce runtime'da hiç yoktu. Geç derleme ve isolate'ler arasında paylaşılan cache'ler, daha büyük uygulamalarda başlangıç işini ve bellek yükünü azaltmalı; bu, Cloudflare'ın 64 MiB'e kadar Node.js projelerini hedeflemesiyle önem taşıyor. Ayrıca sorumluluğu build zamanından runtime'a kaydırıyor, Rolldown gibi araçların dönüşümleri atlamasını sağlıyor ve bundler'ların ürettiği şey ile Node.js'in kendisinin yapacağı şey arasındaki boşluğu daraltıyor. Değişiklik bir compatibility flag'i arkasında geldiğinden ekipler, zorunlu bir geçişe itilmek yerine Worker Worker opt-in yapabiliyor.
- #cloudflare-workers
- #node-js
- #serverless
- #javascript
- #module-resolution