Service Worker'larda ES modülleri

importScripts() için modern bir alternatif.

Arka plan

ES modülleri bir süredir geliştiricilerin favorisi. Diğer birçok avantajın yanı sıra, paylaşılan kodun bir kez yayınlanıp tarayıcılarda ve Node.js gibi alternatif çalışma zamanlarında çalıştırılabileceği evrensel bir modül biçimi sunarlar. Tüm modern tarayıcılar ES modüllerini desteklese de kodun çalıştırılabileceği her yerde destek sunmazlar. Özellikle, tarayıcının hizmet çalışanına ES modüllerini içe aktarma desteği daha yeni yaygınlaşmaya başladı.

Bu makalede, yaygın tarayıcılarda hizmet çalışanlarında ES modülü desteğinin mevcut durumu, kaçınılması gereken bazı sorunlar ve geriye dönük uyumlu hizmet çalışanı kodu göndermeyle ilgili en iyi uygulamalar ayrıntılı olarak açıklanmaktadır.

Kullanım alanları

Hizmet çalışanlarında ES modüllerinin ideal kullanım alanı, ES modüllerini destekleyen diğer çalışma zamanlarıyla paylaşılan modern bir kitaplığı veya yapılandırma kodunu yüklemektir.

ES modüllerinden önce kodu bu şekilde paylaşmaya çalışmak, gereksiz şablonlar içeren UMD gibi eski "evrensel" modül biçimlerinin kullanılmasını ve genel olarak gösterilen değişkenlerde değişiklik yapan kodlar yazılmasını gerektiriyordu.

ES modülleri aracılığıyla içe aktarılan komut dosyaları, içerikleri değişirse hizmet çalışanının güncelleme akışını tetikleyebilir. Bu, importScripts() öğesinin davranışıyla eşleşir.

Mevcut sınırlamalar

Yalnızca statik içe aktarmalar

ES modülleri iki şekilde içe aktarılabilir: import ... from '...' söz dizimini kullanarak statik olarak veya import() yöntemini kullanarak dinamik olarak. Hizmet çalışanında şu anda yalnızca statik söz dizimi desteklenmektedir.

Bu sınırlama, importScripts() kullanımıyla ilgili benzer bir kısıtlamaya benzer. importScripts() için dinamik çağrılar, hizmet çalışanının içinde çalışmaz ve doğası gereği eşzamanlı olan tüm importScripts() çağrıları, hizmet çalışanı install aşamasını tamamlamadan önce tamamlanmalıdır. Bu kısıtlama, tarayıcının hizmet çalışanının yükleme sırasında uygulanması için gereken tüm JavaScript kodunu bilmesini ve dolaylı olarak önbelleğe alabilmesini sağlar.

Bu kısıtlama ileride kaldırılabilir ve dinamik ES modülü içe aktarma işlemlerine izin verilebilir. Şimdilik, hizmet çalışanında yalnızca statik söz dizimini kullandığınızdan emin olun.

Diğer çalışanlar ne durumda?

"Özel" çalışanlardaki ES modülleri (new Worker('...', {type: 'module'}) ile oluşturulanlar) için destek daha yaygındır ve 80 sürümünden beri Chrome ve Edge'de, ayrıca Safari'nin son sürümlerinde desteklenmektedir. Özel çalışanlarda hem statik hem de dinamik ES modülü içe aktarma işlemleri desteklenir.

Chrome ve Edge, 83 sürümünden bu yana paylaşılan çalışanlarda ES modüllerini destekliyor ancak şu anda başka hiçbir tarayıcı bu desteği sunmuyor.

İçe aktarma eşlemeleri desteklenmez.

İçe aktarma eşlemeleri, çalışma zamanı ortamlarının modül belirleyicileri yeniden yazmasına olanak tanır. Örneğin, ES modüllerinin yüklenebileceği tercih edilen bir CDN'nin URL'sini başa ekleyebilir.

Chrome ve Edge'in 89 ve sonraki sürümleri içe aktarma eşlemelerini desteklese de şu anda hizmet çalışanlarıyla kullanılamazlar.

Tarayıcı desteği

Hizmet çalışanlarındaki ES modülleri, 91 sürümünden itibaren Chrome ve Edge'de desteklenir.

Safari, Technology Preview 122 sürümünde destek ekledi. Geliştiriciler, bu işlevin gelecekte Safari'nin kararlı sürümünde yayınlanmasını bekleyebilir.

Örnek kod

Bu, bir web uygulamasının window bağlamında paylaşılan bir ES modülünü kullanmanın ve aynı ES modülünü kullanan bir hizmet çalışanını kaydetmenin temel bir örneğidir:

// Inside config.js:
export const cacheName = 'my-cache';
// Inside your web app:
<script type="module">
  import {cacheName} from './config.js';
  // Do something with cacheName.

  await navigator.serviceWorker.register('es-module-sw.js', {
    type: 'module',
  });
</script>
// Inside es-module-sw.js:
import {cacheName} from './config.js';

self.addEventListener('install', (event) => {
  event.waitUntil((async () => {
    const cache = await caches.open(cacheName);
    // ...
  })());
});

Geriye dönük uyumluluk

Yukarıdaki örnek, tüm tarayıcılar hizmet çalışanlarında ES modüllerini destekliyorsa düzgün çalışır ancak bu makalenin yazıldığı tarih itibarıyla durum böyle değildir.

Yerleşik desteği olmayan tarayıcıları desteklemek için hizmet çalışanı komut dosyanızı ES modülüyle uyumlu bir paketleyici aracılığıyla çalıştırarak tüm modül kodunu satır içi olarak içeren ve eski tarayıcılarda çalışacak bir hizmet çalışanı oluşturabilirsiniz. Alternatif olarak, içe aktarmaya çalıştığınız modüller IIFE veya UMD biçimlerinde paketlenmiş olarak zaten mevcutsa bunları importScripts() kullanarak içe aktarabilirsiniz.

Hizmet çalışanınızın iki sürümü (biri ES modüllerini kullanan, diğeri kullanmayan) kullanıma sunulduktan sonra, mevcut tarayıcının neleri desteklediğini tespit etmeniz ve ilgili hizmet çalışanı komut dosyasını kaydetmeniz gerekir. Destek algılamayla ilgili en iyi uygulamalar şu anda değişmektedir ancak öneriler için bu GitHub sorunundaki tartışmayı takip edebilirsiniz.