Service Worker'larda ES modülleri

importScripts() işlevinin modern bir alternatifidir.

Arka plan

ES modülleri, geliştiricilerin bir süredir tercih ettiği bir çözümdür. 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 ortamlarında çalıştırılabileceği evrensel bir modül biçimi sunarlar. Tüm modern tarayıcılar bazı ES modülü desteği sunsa da bunların tümü, kodun çalıştırılabileceği her yerde destek sunmaz. Özellikle, ES modüllerinin bir tarayıcı hizmet çalışanına aktarılmasıyla ilgili destek daha geniş bir kitleye sunulmaya 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 yayınlamayla ilgili en iyi uygulamalar ayrıntılı olarak açıklanmaktadır.

Kullanım alanları

Hizmet işçileri içindeki ES modülleri için ideal kullanım alanı, ES modüllerini destekleyen diğer çalışma zamanlarıyla paylaşılan modern bir kitaplık veya yapılandırma kodunu yüklemektir.

ES modülleri kullanılmadan önce bu şekilde kod paylaşmaya çalışmak, gereksiz şablonlar içeren UMD gibi eski "evrensel" modül biçimlerini kullanmayı ve genel olarak kullanıma sunulan değişkenlerde değişiklik yapan kod yazmayı gerektiriyordu.

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

Mevcut sınırlamalar

Yalnızca statik içe aktarma

ES modülleri iki şekilde içe aktarılabilir: import ... from '...' söz dizimini kullanarak statik veya import() yöntemini kullanarak dinamik. Şu anda servis çalışanlarının içinde 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 dinamik çağrılar, hizmet işçisi içinde çalışmaz ve doğası gereği senkronize olan tüm importScripts() çağrıları, hizmet işçisi 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 alabilmesini 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.

Diğer çalışanlar için ne yapabilirim?

new Worker('...', {type: 'module'}) ile oluşturulan "özel" işleyicilerdeki ES modülleri için daha yaygın destek sunulur. Bu modüller, 80 sürümü ile birlikte Chrome ve Edge'de, ayrıca Safari'nin son sürümlerinde desteklenir. Ö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 beri ortak çalışanlarda ES modüllerini desteklemektedir ancak şu anda başka hiçbir tarayıcı destek sunmamaktadır.

Harita 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'in 89 sürümü ve sonraki sürümleri içe aktarma haritalarını desteklese de şu anda hizmet işçileriyle kullanamazsınız.

Tarayıcı desteği

Servis çalışanlarındaki ES modülleri, Chrome ve Edge'de 91 sürümünden itibaren 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 hizmet çalışanlarındaki ES modüllerini destekliyorsa yukarıdaki örnek sorunsuz çalışır ancak bu makalenin yazıldığı tarih itibarıyla durum böyle değil.

Yerleşik destek içermeyen tarayıcılara uyum sağlamak için hizmet işleyici komut dosyanızı bir ES modülü uyumlu paketleyici üzerinden çalıştırarak tüm modül kodunu satır içi olarak içeren ve eski tarayıcılarda çalışacak bir hizmet işleyici oluşturabilirsiniz. Alternatif olarak, içe aktarmaya çalıştığınız modüller zaten IIFE veya UMD biçimlerinde paket halinde mevcutsa bunları importScripts() kullanarak içe aktarabilirsiniz.

Servis çalışanınızın iki sürümü (biri ES modüllerini kullanan, diğeri kullanmayan) hazır olduğunda, mevcut tarayıcının neleri desteklediğini tespit etmeniz ve ilgili servis ç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ışmaları takip edebilirsiniz.

_Fotoğraf: Vlado Paunovic, Unsplash_