Service Worker'larda ES modülleri

importScripts() için modern bir alternatif.

Arka plan

ES modülleri bir süredir geliştiricilerin gözdesi. Bir dizi başka 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 vadediyorlar. Tüm modern tarayıcılar bir miktar ES modülü desteği sunsa da hepsi kodun çalıştırılabileceği her yerde destek sunmaz. Özellikle, ES modüllerini bir tarayıcının Service Worker içinde içe aktarma desteği daha yaygın bir şekilde kullanıma sunulmaya başladı.

Bu makalede, yaygın tarayıcılar genelinde hizmet çalışanlarına yönelik ES modülü desteğinin mevcut durumu, kaçınılması gereken bazı avantajlar ve geriye dönük uyumlu Service Worker kodu göndermeyle ilgili en iyi uygulamalar açıklanmaktadır.

Kullanım alanları

Service Worker'lar içindeki ES modüllerinin ideal kullanım alanı, ES modüllerini destekleyen diğer çalışma zamanlarıyla paylaşılan modern bir kütüphanenin veya yapılandırma kodunun yüklenmesidir.

ES modüllerinden önce bu şekilde kod paylaşmaya çalışmak, gereksiz ortak metin içeren UMD gibi eski "evrensel" modül biçimlerini kullanmayı ve küresel olarak etkilenen değişkenlerde değişiklikler yapan kod yazmayı gerektiriyordu.

ES modülleri aracılığıyla içe aktarılan komut dosyaları, içerikleri değişirse importScripts() davranışına uygun şekilde Service Worker güncelleme akışını tetikleyebilir.

Mevcut sınırlamalar

Yalnızca statik içe aktarmalar

ES modülleri şu iki yöntemden biriyle içe aktarılabilir: import ... from '...' söz dizimi kullanılarak statik olarak veya import() yöntemi kullanılarak dinamik olarak. Service Worker içinde şu anda yalnızca statik söz dizimi desteklenmektedir.

Bu sınırlama, importScripts() kullanımına uygulanan benzer bir kısıtlamaya benzer. importScripts() için yapılan dinamik çağrılar, Service Worker içinde çalışmaz ve doğası gereği eşzamanlı olan tüm importScripts() çağrıları, Service Worker install aşamasını tamamlamadan önce tamamlanmalıdır. Bu kısıtlama, tarayıcının yükleme sırasında bir Service Worker'ın uygulaması için gereken tüm JavaScript kodlarını bilmesini ve önbelleğe alınmasını sağlar.

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

Peki ya diğer çalışanlar?

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

Chrome ve Edge, sürüm 83'ten beri paylaşılan çalışanlarda ES modüllerini desteklese de şu anda başka bir tarayıcı desteklenmemektedir.

Haritaları içe aktarma desteği yok

Haritaları içe aktarma, çalışma zamanı ortamlarının modül tanımlayıcıları yeniden yazmasına (örneğin, ES modüllerinin yükleneceği tercih edilen CDN'nin URL'sinin başına eklenmesi) olanak tanır.

Chrome ve Edge 89 sürümü ve sonraki sürümler, içe aktarma haritalarını desteklemektedir ancak şu anda hizmet çalışanlarıyla kullanılamaz.

Tarayıcı desteği

Service Worker'lardaki ES modülleri, 91 sürümünden itibaren Chrome'da ve Edge'de desteklenir.

Safari Teknoloji Önizlemesi 122 Sürümüne destek ekledi. Geliştiriciler bu işlevi ileride Safari'nin kararlı sürümünde kullanıma sunmayı bekleyebilir.

Örnek kod

Bu, bir web uygulamasının window bağlamında paylaşılan bir ES modülü kullanırken aynı ES modülünü kullanan bir hizmet çalışanını kaydetmeye dair temel bir örnektir:

// 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

Tüm tarayıcılar Service Worker'larda ES modüllerini desteklediğinde yukarıdaki örnek işe yarayacaktır. Ancak şu ana kadar böyle bir durum söz konusu değildir.

Yerleşik desteği olmayan tarayıcıları kullanmak için, modül kodunun tamamını satır içi içeren ve eski tarayıcılarda çalışacak bir Service Worker oluşturmak üzere Service Worker komut dosyanızı ES modülüyle uyumlu bir paketleyici üzerinden çalıştırabilirsiniz. Alternatif olarak, içe aktarmaya çalıştığınız modüller zaten IIFE veya UMD biçimlerinde paket halinde bulunuyorsa bunları importScripts() kullanarak içe aktarabilirsiniz.

Service Worker'ınızın iki sürümü hazır olduğunda (biri ES modülleri kullanan, diğeri kullanmayan sürümler), mevcut tarayıcının neyi desteklediğini tespit etmeniz ve ilgili Service Worker 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ışmaları takip edebilirsiniz.

_Fotoğraf: Vlado Paunovic, Unsplash_