Service Worker'larda ES modülleri

importScripts() işlevine 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 vaadinde bulunuyorlar. Tüm modern tarayıcılar bazı ES modülü desteği sunsa da bu kodun çalıştırılabileceği her yerde destek sağlamaz. Özellikle, ES modüllerini bir tarayıcının Service Worker'ının içine aktarma desteği giderek yaygınlaşıyor.

Bu makalede, yaygın tarayıcılardaki Service Worker'larda ES modülü desteğinin mevcut durumu, kaçınılması gereken bazı sorunlar ve geriye dönük uyumlu Service Worker kodu göndermeye yönelik en iyi uygulamalar ayrıntılı bir şekilde açıklanmaktadır.

Kullanım alanları

Service Worker'lar 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 kodu yüklemektir.

ES modüllerinden önce kod bu şekilde paylaşılmaya çalışılması, gereksiz ortak metin içeren UMD gibi eski "evrensel" modül biçimlerinin kullanılmasını ve genel olarak açığa çıkan değişkenlerde değişiklikler yapan kod yazılmasını gerektiriyordu.

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

Mevcut sınırlamalar

Yalnızca statik içe aktarmalar

ES modülleri, 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'ın 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. Ayrıca, 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 hizmet çalışanının uygulaması için gereken tüm JavaScript kodunu bilmesini ve dolaylı olarak önbelleğe alabilmesini sağlar.

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

Peki ya diğer çalışanlar?

"Özel" çalışanlarda ES modülleri (new Worker('...', {type: 'module'}) ile oluşturulanlar) desteği daha yaygındır ve hem 80 sürümünden hem de Safari'nin son sürümlerinden bu yana Chrome ve Edge'de desteklenmektedir. Hem statik hem de dinamik ES modüllerini içe aktarma işlemleri özel çalışanlarda desteklenir.

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

Haritaları içe aktarma desteği yoktur

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

Chrome ve Edge 89 sürümü ve sonraki sürümleri, içe aktarma eşlemelerini desteklese de şu anda hizmet çalışanları tarafından kullanılamaz.

Tarayıcı desteği

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

Safari, Teknoloji Önizlemesi 122 Sürümüne destek eklemiştir. Geliştiricilerin bu işlevi gelecekte Safari'nin kararlı sürümünde kullanıma sunmayı beklemesi gerekmektedir.

Ö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ın kaydedilmesine 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

Yukarıdaki örnek, tüm tarayıcılar Service Worker'larda ES modüllerini desteklemesi halinde sorunsuz bir şekilde çalışır. Ancak, bu yazı hazırlanırken bu durum böyle değildir.

Yerleşik desteği olmayan tarayıcılara uyum sağlamak için Service Worker komut dosyanızı ES modülü uyumlu bir paketleyici üzerinden çalıştırarak modül kodunun tamamını satır içinde içeren ve eski tarayıcılarda çalışacak bir Service Worker oluşturabilirsiniz. Alternatif olarak, içe aktarmaya çalıştığınız modüller zaten IIFE veya UMD biçimlerinde paket hâlindeyse bunları importScripts() kullanarak içe aktarabilirsiniz.

Service Worker'ınızın, biri ES modüllerini kullanan diğeri kullanmayan iki sürümünü edindikten sonra mevcut tarayıcının neleri desteklediğini tespit etmeniz ve ilgili Service Worker komut dosyasını kaydetmeniz gerekir. Desteği 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'in Unsplash_