सर्विस वर्कर को स्क्रिप्ट करना

यह कोडलैब, प्रोग्रेसिव वेब ऐप्लिकेशन डेवलप करने से जुड़े ट्रेनिंग कोर्स का हिस्सा है. इसे Google Developers Training टीम ने बनाया है. अगर कोडलैब को क्रम से पूरा किया जाता है, तो आपको इस कोर्स से सबसे ज़्यादा फ़ायदा मिलेगा.

कोर्स के बारे में पूरी जानकारी के लिए, प्रोग्रेसिव वेब ऐप्लिकेशन डेवलप करने के बारे में खास जानकारी देखें.

परिचय

इस लैब में, आपको एक सामान्य सर्विस वर्कर बनाने का तरीका बताया गया है. साथ ही, सर्विस वर्कर के लाइफ़साइकल के बारे में जानकारी दी गई है.

आपको क्या सीखने को मिलेगा

  • एक बुनियादी सर्विस वर्कर स्क्रिप्ट बनाना, उसे इंस्टॉल करना, और सामान्य डीबग करना

आपको क्या पता होना चाहिए

  • JavaScript और एचटीएमएल की बुनियादी जानकारी
  • ES2015 के Promises के कॉन्सेप्ट और बुनियादी सिंटैक्स
  • डेवलपर कंसोल को चालू करने का तरीका

शुरू करने से पहले आपको क्या चाहिए

github से pwa-training-labs रिपॉज़िटरी को डाउनलोड या क्लोन करें. साथ ही, अगर ज़रूरी हो, तो Node.js का एलटीएस वर्शन इंस्टॉल करें.

service-worker-lab/app/ डायरेक्ट्री में जाएं और लोकल डेवलपमेंट सर्वर शुरू करें:

cd service-worker-lab/app
npm install
node server.js

Ctrl-c की मदद से, सर्वर को किसी भी समय बंद किया जा सकता है.

अपना ब्राउज़र खोलें और localhost:8081/ पर जाएं.

ध्यान दें: सभी सर्विस वर्कर का रजिस्ट्रेशन रद्द करें और लोकल होस्ट के लिए सभी सर्विस वर्कर कैश मिटाएं, ताकि वे लैब में कोई रुकावट न डालें. Chrome DevTools में, ऐप्लिकेशन टैब के स्टोरेज मिटाएं सेक्शन में जाकर, साइट का डेटा मिटाएं पर क्लिक करके ऐसा किया जा सकता है.

अपने पसंदीदा टेक्स्ट एडिटर में service-worker-lab/app/ फ़ोल्डर खोलें. आपको app/ फ़ोल्डर में लैब बनानी होगी.

इस फ़ोल्डर में ये चीज़ें शामिल हैं:

  • below/another.html, js/another.js, js/other.js, और other.html सैंपल संसाधन हैं. इनका इस्तेमाल, सर्विस वर्कर के स्कोप को आज़माने के लिए किया जाता है
  • styles/ फ़ोल्डर में, इस लैब के लिए कैस्केडिंग स्टाइलशीट शामिल हैं
  • test/ फ़ोल्डर में, आपकी प्रोग्रेस को टेस्ट करने के लिए फ़ाइलें मौजूद हैं
  • index.html हमारी सैंपल साइट/ऐप्लिकेशन का मुख्य एचटीएमएल पेज है
  • service-worker.js एक JavaScript फ़ाइल है. इसका इस्तेमाल, हमारे सर्विस वर्कर को बनाने के लिए किया जाता है
  • package.json और package-lock.json, इस प्रोजेक्ट में इस्तेमाल किए गए नोड पैकेज को ट्रैक करते हैं
  • server.js एक सामान्य एक्सप्रेस सर्वर है. इसका इस्तेमाल हम अपने ऐप्लिकेशन को होस्ट करने के लिए करते हैं

अपने टेक्स्ट एडिटर में service-worker.js खोलें. ध्यान दें कि फ़ाइल खाली है. हमने अभी तक सर्विस वर्कर में चलाने के लिए कोई कोड नहीं जोड़ा है.

अपने टेक्स्ट एडिटर में index.html खोलें.

सर्विस वर्कर को रजिस्टर करने के लिए, <script> टैग में यह कोड जोड़ें:

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);
    });
  });
}

स्क्रिप्ट सेव करें और पेज को रीफ़्रेश करें. कंसोल को एक मैसेज दिखाना चाहिए, जिसमें यह बताया गया हो कि सर्विस वर्कर रजिस्टर हो गया है. Chrome में, यह देखा जा सकता है कि कोई सर्विस वर्कर रजिस्टर है या नहीं. इसके लिए, DevTools खोलें. Windows और Linux पर Control + Shift + I या Mac पर ⌘ + alt + I दबाएं. इसके बाद, ऐप्लिकेशन टैब पर क्लिक करें. इसके बाद, सर्विस वर्कर विकल्प पर क्लिक करें. आपको कुछ ऐसा दिखेगा:

ज़रूरी नहीं: साइट को काम न करने वाले ब्राउज़र पर खोलें. इसके बाद, पुष्टि करें कि सहायता से जुड़ी शर्त काम कर रही है.

जानकारी

ऊपर दिया गया कोड, service-worker.js फ़ाइल को सर्विस वर्कर के तौर पर रजिस्टर करता है. यह कुकी सबसे पहले यह जांच करती है कि ब्राउज़र, सर्विस वर्कर के साथ काम करता है या नहीं. आपको हर बार सर्विस वर्कर रजिस्टर करते समय ऐसा करना चाहिए, क्योंकि कुछ ब्राउज़र सर्विस वर्कर के साथ काम नहीं करते. इसके बाद, कोड ServiceWorkerContainer API के register तरीके का इस्तेमाल करके, सर्विस वर्कर को रजिस्टर करता है. यह Navigator इंटरफ़ेस की विंडो में शामिल होता है.

navigator.serviceWorker.register(...) एक प्रॉमिस दिखाता है. जब सर्विस वर्कर रजिस्टर हो जाता है, तब यह प्रॉमिस registration ऑब्जेक्ट के साथ रिज़ॉल्व हो जाता है. अगर रजिस्ट्रेशन नहीं होता है, तो प्रॉमिस अस्वीकार कर दिया जाएगा.

सर्विस वर्कर के स्टेटस में हुए बदलावों से, सर्विस वर्कर में इवेंट ट्रिगर होते हैं.

इवेंट लिसनर जोड़ना

अपने टेक्स्ट एडिटर में service-worker.js खोलें.

सर्विस वर्कर में ये इवेंट लिसनर जोड़ें:

self.addEventListener('install', event => {
  console.log('Service worker installing...');
  // Add a call to skipWaiting here
});

self.addEventListener('activate', event => {
  console.log('Service worker activating...');
});

फ़ाइल सेव करें.

सर्विस वर्कर को मैन्युअल तरीके से अनरजिस्टर करें. इसके बाद, अपडेट किए गए सर्विस वर्कर को इंस्टॉल और चालू करने के लिए, पेज को रीफ़्रेश करें. कंसोल लॉग में यह दिखना चाहिए कि नया सर्विस वर्कर रजिस्टर, इंस्टॉल, और चालू हो गया है.

ध्यान दें: ऐसा हो सकता है कि रजिस्ट्रेशन लॉग, अन्य लॉग (इंस्टॉलेशन और ऐक्टिवेशन) के साथ क्रम से न दिखे. सर्विस वर्कर, पेज के साथ-साथ चलता है. इसलिए, हम लॉग के क्रम की गारंटी नहीं दे सकते. रजिस्ट्रेशन लॉग, पेज से आता है. वहीं, इंस्टॉलेशन और ऐक्टिवेशन लॉग, सर्विस वर्कर से आते हैं. सर्विस वर्कर में इंस्टॉलेशन, चालू करने, और सर्विस वर्कर से जुड़ी अन्य इवेंट, तय किए गए क्रम में होते हैं. हालांकि, इन्हें हमेशा तय किए गए क्रम में दिखना चाहिए.

जानकारी

रजिस्ट्रेशन के आखिर में, सर्विस वर्कर एक install इवेंट भेजता है. ऊपर दिए गए कोड में, install इवेंट लिसनर के अंदर एक मैसेज लॉग किया गया है. हालांकि, असल ज़िंदगी में इस्तेमाल होने वाले ऐप्लिकेशन में, यह स्टैटिक ऐसेट को कैश मेमोरी में सेव करने के लिए एक अच्छी जगह होगी.

जब कोई सर्विस वर्कर रजिस्टर किया जाता है, तो ब्राउज़र यह पता लगाता है कि सर्विस वर्कर नया है या नहीं. ऐसा इसलिए होता है, क्योंकि यह पहले से इंस्टॉल किए गए सर्विस वर्कर से अलग होता है या इस साइट के लिए कोई सर्विस वर्कर रजिस्टर नहीं होता है. अगर सर्विस वर्कर नया है (जैसा कि इस मामले में है), तो ब्राउज़र उसे इंस्टॉल करता है.

जब सर्विस वर्कर पेज का कंट्रोल लेता है, तब वह activate इवेंट को ट्रिगर करता है. ऊपर दिया गया कोड, यहां एक मैसेज लॉग करता है. हालांकि, इस इवेंट का इस्तेमाल अक्सर कैश मेमोरी को अपडेट करने के लिए किया जाता है.

किसी दिए गए स्कोप के लिए, एक बार में सिर्फ़ एक सर्विस वर्कर चालू हो सकता है. इसके बारे में जानने के लिए, सर्विस वर्कर का स्कोप एक्सप्लोर करना लेख पढ़ें. इसलिए, नया सर्विस वर्कर तब तक चालू नहीं होता, जब तक मौजूदा सर्विस वर्कर का इस्तेमाल नहीं किया जाता. इसलिए, सर्विस वर्कर के कंट्रोल वाले सभी पेजों को बंद करना ज़रूरी है, ताकि नया सर्विस वर्कर कंट्रोल कर सके. हमने मौजूदा सर्विस वर्कर का रजिस्ट्रेशन रद्द कर दिया है. इसलिए, नया सर्विस वर्कर तुरंत चालू हो गया.

ध्यान दें: सिर्फ़ पेज को रीफ़्रेश करने से, कंट्रोल को नए सर्विस वर्कर पर ट्रांसफ़र नहीं किया जा सकता. ऐसा इसलिए, क्योंकि मौजूदा पेज के अनलोड होने से पहले ही नए पेज का अनुरोध किया जाएगा. साथ ही, ऐसा कोई समय नहीं होगा, जब पुराने सर्विस वर्कर का इस्तेमाल न किया जा रहा हो.

ध्यान दें: कुछ ब्राउज़र के डेवलपर टूल का इस्तेमाल करके, नए सर्विस वर्कर को मैन्युअल तरीके से भी चालू किया जा सकता है. इसके अलावा, skipWaiting() का इस्तेमाल करके प्रोग्राम के हिसाब से भी इसे चालू किया जा सकता है. इसके बारे में हमने सेक्शन 3.4 में बताया है.

सर्विस वर्कर को अपडेट करना

service-worker.js में यहां दी गई टिप्पणी कहीं भी जोड़ें:

// I'm a new service worker

फ़ाइल सेव करें और पेज को रीफ़्रेश करें. कंसोल में लॉग देखें. ध्यान दें कि नया सर्विस वर्कर इंस्टॉल हो जाता है, लेकिन चालू नहीं होता. Chrome में, DevTools के ऐप्लिकेशन टैब में, इंतज़ार कर रहे सर्विस वर्कर को देखा जा सकता है.

सर्विस वर्कर से जुड़े सभी पेज बंद करें. इसके बाद, localhost:8081/ को फिर से खोलें. कंसोल लॉग से पता चलना चाहिए कि नया सर्विस वर्कर अब चालू हो गया है.

ध्यान दें: अगर आपको उम्मीद के मुताबिक नतीजे नहीं मिल रहे हैं, तो पक्का करें कि डेवलपर टूल में आपकी एचटीटीपी कैश मेमोरी बंद हो.

जानकारी

ब्राउज़र को नई और मौजूदा सर्विस वर्कर फ़ाइल के बीच बाइट का अंतर पता चलता है. ऐसा जोड़ी गई टिप्पणी की वजह से होता है. इसलिए, नया सर्विस वर्कर इंस्टॉल किया जाता है. किसी दिए गए स्कोप के लिए, एक बार में सिर्फ़ एक सर्विस वर्कर चालू हो सकता है. इसलिए, नया सर्विस वर्कर इंस्टॉल होने के बावजूद, तब तक चालू नहीं होता, जब तक मौजूदा सर्विस वर्कर का इस्तेमाल नहीं किया जाता. पुराने सर्विस वर्कर के कंट्रोल में मौजूद सभी पेजों को बंद करके, हम नए सर्विस वर्कर को चालू कर सकते हैं.

इंतज़ार की अवधि को छोड़ना

नया सर्विस वर्कर, इंतज़ार की अवधि को छोड़कर तुरंत चालू हो सकता है. भले ही, कोई मौजूदा सर्विस वर्कर मौजूद हो.

service-worker.js में, install इवेंट लिसनर में skipWaiting को कॉल करें:

self.skipWaiting();

फ़ाइल सेव करें और पेज को रीफ़्रेश करें. ध्यान दें कि नया सर्विस वर्कर तुरंत इंस्टॉल और चालू हो जाता है. भले ही, पिछला सर्विस वर्कर कंट्रोल में हो.

जानकारी

skipWaiting() तरीके से, सर्विस वर्कर को इंस्टॉल होने के तुरंत बाद चालू किया जा सकता है. इंस्टॉल इवेंट लिस्नर, skipWaiting() कॉल को रखने की एक सामान्य जगह है. हालांकि, इसे इंतज़ार के दौरान या उससे पहले कहीं भी कॉल किया जा सकता है. skipWaiting() का इस्तेमाल कब और कैसे करना है, इस बारे में ज़्यादा जानने के लिए यह दस्तावेज़ देखें. अब हम लैब के बाकी हिस्से के लिए, नए सर्विस वर्कर कोड की जांच कर सकते हैं. इसके लिए, हमें सर्विस वर्कर को मैन्युअल तरीके से अनरजिस्टर करने की ज़रूरत नहीं होगी.

अधिक जानकारी के लिए

सर्विस वर्कर, आपके वेब ऐप्लिकेशन और नेटवर्क के बीच प्रॉक्सी के तौर पर काम कर सकते हैं.

आइए, अपने डोमेन से किए गए अनुरोधों को इंटरसेप्ट करने के लिए, फ़ेच लिसनर जोड़ें.

service-worker.js में यह कोड जोड़ें:

self.addEventListener('fetch', event => {
  console.log('Fetching:', event.request.url);
});

स्क्रिप्ट को सेव करें और पेज को रीफ़्रेश करें, ताकि अपडेट किया गया सर्विस वर्कर इंस्टॉल और चालू हो सके.

कंसोल देखें और देखें कि कोई फ़ेच इवेंट लॉग नहीं किया गया है. पेज को रीफ़्रेश करें और कंसोल को फिर से देखें. इस बार आपको पेज और उसकी ऐसेट (जैसे कि सीएसएस) के लिए, फ़ेच इवेंट दिखने चाहिए.

अन्य पेज, दूसरा पेज, और वापस जाएं लिंक पर क्लिक करें.

आपको हर पेज और उसकी ऐसेट के लिए, कंसोल में फ़ेच इवेंट दिखेंगे. क्या सभी लॉग का कोई मतलब है?

ध्यान दें: अगर किसी पेज पर जाने के दौरान, एचटीटीपी कैश मेमोरी बंद नहीं की जाती है, तो सीएसएस और JavaScript ऐसेट को स्थानीय तौर पर कैश मेमोरी में सेव किया जा सकता है. ऐसा होने पर, आपको इन संसाधनों के लिए फ़ेच इवेंट नहीं दिखेंगे.

जानकारी

सर्विस वर्कर को, ब्राउज़र के किए गए हर एचटीटीपी अनुरोध के लिए फ़ेच इवेंट मिलता है. यह अनुरोध, सर्विस वर्कर के स्कोप में होना चाहिए. fetch event ऑब्जेक्ट में अनुरोध शामिल होता है. सर्विस वर्कर में फ़ेच इवेंट को सुनने की सुविधा, डीओएम में क्लिक इवेंट को सुनने की सुविधा की तरह ही होती है. हमारे कोड में, जब फ़ेच इवेंट होता है, तब हम अनुरोध किए गए यूआरएल को कंसोल में लॉग करते हैं. हालांकि, हम चाहें, तो अपनी पसंद के मुताबिक कोई रिस्पॉन्स भी बना सकते हैं और उसे किसी भी संसाधन के साथ वापस भेज सकते हैं.

पहले रीफ़्रेश पर, फ़ेच इवेंट लॉग क्यों नहीं हुए? डिफ़ॉल्ट रूप से, किसी पेज से फ़ेच किए गए इवेंट, सर्विस वर्कर से नहीं गुज़रेंगे. हालांकि, ऐसा तब होगा, जब पेज का अनुरोध खुद सर्विस वर्कर से गुज़रा हो. इससे आपकी साइट पर एक जैसा अनुभव मिलता है. अगर कोई पेज सर्विस वर्कर के बिना लोड होता है, तो उसके सब-रिसोर्स भी लोड हो जाते हैं.

अधिक जानकारी के लिए

सॉल्यूशन कोड

काम करने वाले कोड की कॉपी पाने के लिए, 04-intercepting-network-requests/ फ़ोल्डर पर जाएं.

सर्विस वर्कर का स्कोप होता है. सर्विस वर्कर का स्कोप यह तय करता है कि सर्विस वर्कर, किन पाथ से अनुरोधों को इंटरसेप्ट करता है.

स्कोप ढूंढना

index.html में रजिस्ट्रेशन कोड को इससे अपडेट करें:

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);
    });
  });
}

ब्राउज़र को रीफ़्रेश करें. ध्यान दें कि कंसोल में सर्विस वर्कर का स्कोप दिखाया गया है. इस मामले में, यह http://localhost:8081/ है.

जानकारी

register() से मिला प्रॉमिस, registration object में बदल जाता है. इसमें सर्विस वर्कर का स्कोप होता है.

डिफ़ॉल्ट स्कोप, सर्विस वर्कर फ़ाइल का पाथ होता है. यह सभी लोअर डायरेक्ट्री तक फैला होता है. इसलिए, किसी ऐप्लिकेशन की रूट डायरेक्ट्री में मौजूद सर्विस वर्कर, ऐप्लिकेशन की सभी फ़ाइलों से किए गए अनुरोधों को कंट्रोल करता है.

सर्विस वर्कर को दूसरी जगह ले जाना

service-worker.js को below/ डायरेक्ट्री में ले जाएं. साथ ही, index.html में रजिस्ट्रेशन कोड में मौजूद सर्विस वर्कर यूआरएल को अपडेट करें.

ब्राउज़र में मौजूद मौजूदा सर्विस वर्कर का रजिस्ट्रेशन रद्द करें और पेज को रीफ़्रेश करें.

कंसोल में दिखता है कि सर्विस वर्कर का स्कोप अब http://localhost:8081/below/ है. Chrome में, DevTools के ऐप्लिकेशन टैब में भी सर्विस वर्कर का स्कोप देखा जा सकता है:

मुख्य पेज पर वापस जाकर, अन्य पेज, कोई दूसरा पेज, और वापस जाएं पर क्लिक करें. किन फ़ेच अनुरोधों को लॉग किया जा रहा है? कौनसी कुकी नहीं हैं?

जानकारी

सर्विस वर्कर का डिफ़ॉल्ट स्कोप, सर्विस वर्कर फ़ाइल का पाथ होता है. अब सर्विस वर्कर फ़ाइल below/ में है. इसलिए, यह इसका स्कोप है. अब कंसोल सिर्फ़ another.html, another.css, और another.js के लिए फ़ेच इवेंट लॉग कर रहा है, क्योंकि ये ही संसाधन सर्विस वर्कर के दायरे में आते हैं.

कोई भी स्कोप सेट करना

सर्विस वर्कर को वापस प्रोजेक्ट की रूट डायरेक्ट्री (app/) में ले जाएं. साथ ही, index.html में रजिस्ट्रेशन कोड में सर्विस वर्कर का यूआरएल अपडेट करें.

register() में मौजूद वैकल्पिक पैरामीटर का इस्तेमाल करके, सर्विस वर्कर के स्कोप को below/ डायरेक्ट्री पर सेट करने के लिए, MDN पर मौजूद रेफ़रंस का इस्तेमाल करें.

सर्विस वर्कर का रजिस्ट्रेशन रद्द करें और पेज को रीफ़्रेश करें. अन्य पेज, कोई दूसरा पेज, और वापस जाएं पर क्लिक करें.

कंसोल फिर से दिखाता है कि अब सर्विस वर्कर का स्कोप http://localhost:8081/below/ है. साथ ही, यह सिर्फ़ another.html, another.css, और another.js के लिए फ़ेच इवेंट लॉग करता है.

जानकारी

रजिस्टर करते समय कोई अतिरिक्त पैरामीटर पास करके, कोई भी स्कोप सेट किया जा सकता है. उदाहरण के लिए:

navigator.serviceWorker.register('/service-worker.js', {
  scope: '/kitten/'
});

ऊपर दिए गए उदाहरण में, सर्विस वर्कर का स्कोप /kitten/ पर सेट है. सर्विस वर्कर, /kitten/ और /kitten/lower/ में मौजूद पेजों से मिले अनुरोधों को इंटरसेप्ट करता है. हालांकि, वह /kitten या / जैसे पेजों से मिले अनुरोधों को इंटरसेप्ट नहीं करता.

ध्यान दें: ऐसा स्कोप सेट नहीं किया जा सकता जो सर्विस वर्कर की मौजूदा जगह से ज़्यादा हो. हालांकि, अगर आपका सर्वर वर्कर, Service-Worker-Allowed हेडर के साथ सेवा देने वाले क्लाइंट पर चालू है, तो उस सर्वर वर्कर के लिए, सर्वर वर्कर की जगह से ऊपर का ज़्यादा से ज़्यादा स्कोप तय किया जा सकता है.

अधिक जानकारी के लिए

सॉल्यूशन कोड

काम करने वाले कोड की कॉपी पाने के लिए, solution/ फ़ोल्डर पर जाएं.

अब आपके पास एक सामान्य सर्विस वर्कर है, जो काम कर रहा है. साथ ही, आपको सर्विस वर्कर के लाइफ़साइकल के बारे में भी पता है.

अधिक जानकारी के लिए

सर्विस वर्कर का लाइफ़ साइकल

PWA ट्रेनिंग कोर्स में मौजूद सभी कोडलैब देखने के लिए, कोर्स का वेलकम कोडलैब देखें/