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ı için 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 bir hizmet çalışanının kurulumu sırasında uygulanması için gereken tüm JavaScript kodlarını bilmesi ve dolaylı olarak önbelleğe alabilmesini sağlar.

Bu kısıtlama zaman içinde kaldırılabilir ve dinamik ES modülü içe aktarmalarına izin verilebilir. Şimdilik yalnızca bir hizmet çalışanının içinde statik söz dizimini 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 yoktur.

Haritaları içe aktarma, çalışma ortamının modül belirteçlerini yeniden yazmasına olanak tanır. Örneğin, ES modüllerinin yüklenebileceği tercih edilen bir CDN'nin URL'sini öne eklemek için kullanılı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, Technology Preview 122 Sürümü'nde bu işleve destek ekledi. Geliştiriciler, bu işlevin gelecekte Safari'nin kararlı sürümünde kullanıma sunulmasını bekleyebilir.

Örnek kod

Bu, bir web uygulamasının bağlamında paylaşılan bir ES modülünün kullanıldığı ve aynı ES modülünü kullanan bir hizmet çalışanının da kaydedildiği temel bir örnektir:window

// 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. Desteği algılamayla ilgili en iyi uygulamalar şu anda değişiyor ancak öneriler için bu GitHub sorunundaki tartışmayı takip edebilirsiniz.

_Fotoğraf: Vlado Paunovic, Unsplash_