Bu codelab, Google Developers Training ekibi tarafından geliştirilen Progresif Web Uygulamaları Geliştirme eğitim kursunun bir parçasıdır. Bu kurstan en iyi şekilde yararlanmak için codelab'leri sırayla tamamlamanız önerilir.
Kursla ilgili tüm ayrıntılar için Progresif web uygulamaları geliştirme genel bakış başlıklı makaleyi inceleyin.
Giriş
Bu laboratuvarda, basit bir hizmet çalışanı oluşturma süreci adım adım açıklanır ve hizmet çalışanı yaşam döngüsü anlatılır.
Neler öğreneceksiniz?
- Temel bir service worker komut dosyası oluşturma, yükleme ve basit hata ayıklama işlemleri yapma
Bilmeniz gerekenler
- Temel JavaScript ve HTML
- ES2015 Promises ile ilgili kavramlar ve temel söz dizimi
- Geliştirici konsolunu etkinleştirme
Başlamadan önce ihtiyacınız olanlar
- Terminal/kabuk erişimi olan bir bilgisayar
- İnternet bağlantısı
- Service worker'ları destekleyen bir tarayıcı
- Metin düzenleyici
GitHub'dan pwa-training-labs deposunu indirin veya klonlayın ve gerekirse Node.js'nin LTS sürümünü yükleyin.
service-worker-lab/app/ dizinine gidin ve yerel bir geliştirme sunucusu başlatın:
cd service-worker-lab/app npm install node server.js
Sunucuyu Ctrl-c ile istediğiniz zaman sonlandırabilirsiniz.
Tarayıcınızı açıp localhost:8081/ adresine gidin.
Not: Laboratuvarı etkilememeleri için tüm hizmet çalışanlarının kaydını iptal edin ve localhost için tüm hizmet çalışanı önbelleklerini temizleyin. Chrome Geliştirici Araçları'nda, Uygulama sekmesinin Depolamayı temizle bölümünden Site verilerini temizle'yi tıklayarak bunu yapabilirsiniz.
service-worker-lab/app/ klasörünü tercih ettiğiniz metin düzenleyicide açın. Laboratuvarı app/ klasöründe oluşturacaksınız.
Bu klasörde şunlar bulunur:
below/another.html,js/another.js,js/other.jsveother.html, hizmet çalışanı kapsamıyla deneme yapmak için kullandığımız örnek kaynaklardır.styles/klasörü, bu laboratuvarın basamaklı stil sayfalarını içerir.test/klasörü, ilerlemenizi test etmeye yönelik dosyalar içeririndex.html, örnek sitemizin/uygulamamızın ana HTML sayfasıdır.service-worker.js, hizmet çalışanımızı oluşturmak için kullanılan JavaScript dosyasıdır.package.jsonvepackage-lock.json, bu projede kullanılan düğüm paketlerini izler.server.js, uygulamamızı barındırmak için kullandığımız basit bir Express sunucusudur.
service-worker.js dosyasını metin düzenleyicinizde açın. Dosyanın boş olduğunu unutmayın. Henüz hizmet çalışanı içinde çalışacak herhangi bir kod eklemedik.
index.html dosyasını metin düzenleyicinizde açın.
<script> etiketlerinin içine, hizmet çalışanını kaydetmek için aşağıdaki kodu ekleyin:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('Service Worker is registered', registration);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}Komut dosyasını kaydedin ve sayfayı yenileyin. Konsol, service worker'ın kaydedildiğini belirten bir mesaj döndürmelidir. Chrome'da, bir hizmet çalışanının kaydedildiğini kontrol etmek için Geliştirici Araçları'nı açabilir (Windows ve Linux'ta Control + Üst Karakter + I veya Mac'te ⌘ + alt + I), Uygulama sekmesini ve ardından Hizmet Çalışanları seçeneğini tıklayabilirsiniz. Aşağıdakine benzer bir ifade görürsünüz:

İsteğe bağlı: Siteyi desteklenmeyen bir tarayıcıda açın ve destek kontrolü koşullu işleminin çalıştığını doğrulayın.
Açıklama
Yukarıdaki kod, service-worker.js dosyasını bir hizmet çalışanı olarak kaydeder. Öncelikle tarayıcının hizmet çalışanlarını destekleyip desteklemediğini kontrol eder. Bazı tarayıcılar hizmet çalışanlarını desteklemeyebileceğinden, hizmet çalışanı her kaydettiğinizde bu işlemi yapmanız gerekir. Ardından kod, pencerenin Navigator arayüzünde bulunan ServiceWorkerContainer API'nin register yöntemini kullanarak hizmet çalışanını kaydeder.
navigator.serviceWorker.register(...), hizmet çalışanı başarıyla kaydedildikten sonra registration nesnesiyle çözümlenen bir söz döndürür. Kayıt başarısız olursa söz reddedilir.
Hizmet çalışanın durumundaki değişiklikler, hizmet çalışanında etkinlikleri tetikler.
Etkinlik işleyicileri ekleme
service-worker.js dosyasını metin düzenleyicinizde açın.
Aşağıdaki etkinlik işleyicileri hizmet çalışanına ekleyin:
self.addEventListener('install', event => {
console.log('Service worker installing...');
// Add a call to skipWaiting here
});
self.addEventListener('activate', event => {
console.log('Service worker activating...');
});Dosyayı kaydedin.
Hizmet çalışanının kaydını manuel olarak iptal edin ve güncellenen hizmet çalışanını yükleyip etkinleştirmek için sayfayı yenileyin. Konsol günlüğünde, yeni hizmet çalışanının kaydedildiği, yüklendiği ve etkinleştirildiği belirtilmelidir.
Not: Kayıt günlüğü, diğer günlüklerle (yükleme ve etkinleştirme) birlikte sıralı görünmeyebilir. Hizmet çalışanı, sayfayla eşzamanlı olarak çalıştığından günlüklerin sırasını garanti edemeyiz (kayıt günlüğü sayfadan, yükleme ve etkinleştirme günlükleri ise hizmet çalışanından gelir). Yükleme, etkinleştirme ve diğer hizmet çalışanı etkinlikleri, hizmet çalışanının içinde tanımlanmış bir sırayla gerçekleşir ve her zaman beklenen sırada görünmelidir.
Açıklama
Service worker, kaydın sonunda bir install etkinliği yayınlar. Yukarıdaki kodda, install etkinlik işleyicisinin içinde bir ileti kaydedilir ancak gerçek dünyadaki bir uygulamada bu, statik öğeleri önbelleğe almak için iyi bir yer olurdu.
Bir hizmet çalışanı kaydedildiğinde tarayıcı, hizmet çalışanının yeni olup olmadığını (önceden yüklenen hizmet çalışanından farklı olduğu veya bu site için kayıtlı bir hizmet çalışanı olmadığı için) algılar. Service worker yeni ise (bu örnekte olduğu gibi) tarayıcı onu yükler.
Hizmet çalışanı, sayfanın kontrolünü ele aldığında activate etkinliğini yayınlar. Yukarıdaki kod, buraya bir mesaj kaydeder ancak bu etkinlik genellikle önbellekleri güncellemek için kullanılır.
Belirli bir kapsam için aynı anda yalnızca bir hizmet çalışanı etkin olabilir (bkz. Hizmet çalışanı kapsamını keşfetme). Bu nedenle, yeni yüklenen bir hizmet çalışanı, mevcut hizmet çalışanı artık kullanılmayana kadar etkinleştirilmez. Bu nedenle, yeni bir hizmet çalışanı devralmadan önce hizmet çalışanı tarafından kontrol edilen tüm sayfaların kapatılması gerekir. Mevcut hizmet çalışanı kaydı iptal edildiğinden yeni hizmet çalışanı hemen etkinleştirildi.
Not: Yeni sayfa, mevcut sayfa kaldırılmadan önce istendiği ve eski hizmet çalışanı kullanılmadığı bir zaman olmayacağı için kontrolü yeni bir hizmet çalışanına aktarmak için sayfayı yenilemek yeterli değildir.
Not: Bazı tarayıcıların geliştirici araçlarını kullanarak yeni bir hizmet çalışanını manuel olarak da etkinleştirebilirsiniz. Ayrıca, 3.4 bölümünde ele aldığımız skipWaiting() ile programatik olarak da etkinleştirebilirsiniz.
Service worker'ı güncelleme
Aşağıdaki yorumu service-worker.js içinde herhangi bir yere ekleyin:
// I'm a new service workerDosyayı kaydedin ve sayfayı yenileyin. Konsoldaki günlükleri inceleyin. Yeni hizmet çalışanının yüklendiğini ancak etkinleştirilmediğini fark edeceksiniz. Chrome'da bekleyen hizmet çalışanını Geliştirici Araçları'ndaki Uygulama sekmesinde görebilirsiniz.

Service worker ile ilişkili tüm sayfaları kapatın. Ardından localhost:8081/ simgesini yeniden açın. Konsol günlüğünde, yeni hizmet çalışanının etkinleştirildiği belirtilmelidir.
Not: Beklenmedik sonuçlar alıyorsanız geliştirici araçlarında HTTP önbelleğinizin devre dışı olduğundan emin olun.
Açıklama
Tarayıcı, yeni ve mevcut hizmet çalışanı dosyası arasında bir bayt farkı algılar (eklenen yorum nedeniyle). Bu nedenle, yeni hizmet çalışanı yüklenir. Belirli bir kapsam için aynı anda yalnızca bir hizmet çalışanı etkin olabileceğinden, yeni hizmet çalışanı yüklense bile mevcut hizmet çalışanı kullanılmayana kadar etkinleştirilmez. Eski hizmet çalışanının kontrolündeki tüm sayfaları kapatarak yeni hizmet çalışanını etkinleştirebiliriz.
Bekleme aşamasını atlama
Yeni bir hizmet çalışanı, bekleme aşamasını atlayarak mevcut bir hizmet çalışanı olsa bile hemen etkinleşebilir.
service-worker.js içinde, install etkinlik işleyicisinde skipWaiting için bir çağrı ekleyin:
self.skipWaiting();Dosyayı kaydedin ve sayfayı yenileyin. Önceki bir hizmet çalışanı kontrolü ele almış olsa bile yeni hizmet çalışanının hemen yüklendiğini ve etkinleştirildiğini unutmayın.
Açıklama
skipWaiting() yöntemi, hizmet çalışanının yüklemeyi tamamlar tamamlamaz etkinleşmesine olanak tanır. Yükleme etkinliği işleyicisi, skipWaiting() çağrısının yerleştirileceği yaygın bir yerdir ancak bekleme aşamasında veya öncesinde herhangi bir yerde çağrılabilir. skipWaiting()'ı ne zaman ve nasıl kullanacağınız hakkında daha fazla bilgi için bu belgeye bakın. Laboratuvarın geri kalanında, hizmet çalışanını manuel olarak kaydını silmeden yeni hizmet çalışanı kodunu test edebiliriz.
Daha fazla bilgi için
Hizmet çalışanları, web uygulamanız ile ağ arasında proxy görevi görebilir.
Alanımızdan gelen istekleri yakalamak için bir getirme işleyici ekleyelim.
Aşağıdaki kodu service-worker.js dosyasına ekleyin:
self.addEventListener('fetch', event => {
console.log('Fetching:', event.request.url);
});Güncellenen hizmet çalışanını yüklemek ve etkinleştirmek için komut dosyasını kaydedip sayfayı yenileyin.
Konsolu kontrol edin ve herhangi bir getirme etkinliğinin kaydedilmediğini gözlemleyin. Sayfayı yenileyip konsolu tekrar kontrol edin. Bu kez sayfa ve öğeleri (CSS gibi) için getirme etkinliklerini görmeniz gerekir.
Diğer sayfa, Başka bir sayfa ve Geri bağlantılarını tıklayın.
Her sayfa ve öğesi için konsolda getirme etkinliklerini görürsünüz. Tüm günlükler anlamlı mı?
Not: Bir sayfayı ziyaret ettiğinizde HTTP önbelleği devre dışı değilse CSS ve JavaScript öğeleri yerel olarak önbelleğe alınabilir. Bu durumda, bu kaynaklar için getirme etkinliklerini görmezsiniz.
Açıklama
Service worker, tarayıcının kendi kapsamı içinde yaptığı her HTTP isteği için bir getirme etkinliği alır. Fetch event nesnesi, isteği içerir. Service worker'da getirme etkinliklerini dinlemek, DOM'da tıklama etkinliklerini dinlemeye benzer. Kodumuzda, bir getirme etkinliği gerçekleştiğinde istenen URL'yi konsola kaydediyoruz (uygulamada, rastgele kaynaklarla kendi özel yanıtımızı da oluşturup döndürebiliriz).
İlk yenilemede neden herhangi bir getirme etkinliği günlüğe kaydedilmedi? Varsayılan olarak, sayfa isteği hizmet çalışanından geçmediği sürece bir sayfadan alınan etkinlikler hizmet çalışanından geçmez. Bu, sitenizde tutarlılık sağlar. Bir sayfa hizmet çalışanı olmadan yüklenirse alt kaynakları da hizmet çalışanı olmadan yüklenir.
Daha fazla bilgi için
Çözüm kodu
Çalışan kodun bir kopyasını almak için 04-intercepting-network-requests/ klasörüne gidin.
Hizmet çalışanlarının kapsamı vardır. Hizmet çalışanının kapsamı, hizmet çalışanının hangi yollardan gelen istekleri yakalayacağını belirler.
Kapsamı bulma
index.html'daki kayıt kodunu aşağıdakilerle güncelleyin:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('SW registered with scope:', registration.scope);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}Tarayıcıyı yenileyin. Konsolun, hizmet çalışanının kapsamını (bu örnekte http://localhost:8081/) gösterdiğini unutmayın.
Açıklama
register() tarafından döndürülen söz, hizmet çalışanın kapsamını içeren kayıt nesnesi olarak çözümlenir.
Varsayılan kapsam, hizmet çalışanı dosyasının yoludur ve daha düşük tüm dizinleri kapsar. Bu nedenle, bir uygulamanın kök dizinindeki bir hizmet çalışanı, uygulamadaki tüm dosyalardan gelen istekleri kontrol eder.
Hizmet çalışanını taşıma
service-worker.js dosyasını below/ dizinine taşıyın ve index.html içindeki kayıt kodunda hizmet çalışanı URL'sini güncelleyin.
Tarayıcıda geçerli hizmet çalışanının kaydını iptal edin ve sayfayı yenileyin.
Konsolda, hizmet çalışanın kapsamının artık http://localhost:8081/below/ olduğu gösteriliyor. Chrome'da, Geliştirici Araçları'nın uygulama sekmesinde hizmet çalışanı kapsamını da görebilirsiniz:

Ana sayfaya dönüp Diğer sayfa, Başka bir sayfa ve Geri'yi tıklayın. Hangi getirme istekleri günlüğe kaydedilir? Hangileri değil?
Açıklama
Service worker'ın varsayılan kapsamı, service worker dosyasının yoludur. Service worker dosyası artık below/ içinde olduğundan kapsamı da below/ olur. Konsol artık yalnızca hizmet çalışanının kapsamındaki kaynaklar olduğu için another.html, another.css ve another.js için getirme etkinliklerini günlüğe kaydediyor.
Rastgele bir kapsam ayarlama
Service worker'ı proje kök dizinine (app/) geri taşıyın ve index.html içindeki kayıt kodunda service worker URL'sini güncelleyin.
register() içindeki isteğe bağlı parametreyi kullanarak hizmet çalışanının kapsamını below/ dizini olarak ayarlamak için MDN'deki referansı kullanın.
Hizmet çalışanının kaydını iptal edin ve sayfayı yenileyin. Diğer sayfa, Başka bir sayfa ve Geri'yi tıklayın.
Konsol, hizmet çalışanın kapsamının artık http://localhost:8081/below/ olduğunu ve yalnızca another.html, another.css ve another.js için getirme etkinliklerinin kaydedildiğini gösteriyor.
Açıklama
Kayıt sırasında ek bir parametre ileterek rastgele bir kapsam ayarlamak mümkündür. Örneğin:
navigator.serviceWorker.register('/service-worker.js', {
scope: '/kitten/'
});Yukarıdaki örnekte hizmet çalışanın kapsamı /kitten/ olarak ayarlanmıştır. Hizmet çalışanı, /kitten/ ve /kitten/lower/ içindeki sayfalardan gelen istekleri yakalar ancak /kitten veya / gibi sayfalardan gelen istekleri yakalamaz.
Not: Hizmet çalışanın gerçek konumunun üzerinde rastgele bir kapsam ayarlayamazsınız. Ancak sunucu çalışanı, Service-Worker-Allowed üstbilgisiyle sunulan bir istemcide etkinse bu hizmet çalışanı için hizmet çalışanının konumunun üzerinde bir maksimum kapsam belirtebilirsiniz.
Daha fazla bilgi için
Çözüm kodu
Çalışan kodun bir kopyasını almak için solution/ klasörüne gidin.
Artık basit bir hizmet çalışanınız çalışıyor ve hizmet çalışanı yaşam döngüsünü anlıyorsunuz.
Daha fazla bilgi için
PWA eğitim kursundaki tüm codelab'leri görmek için kursun Hoş geldiniz codelab'ine göz atın.