सर्विस वर्कर

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

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

परिचय

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

आप इन चीज़ों के बारे में जानेंगे

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

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

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

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

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

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 पर कंट्रोल + Shift + I या Mac पर ⌘ + Alt + I) खोलकर, ऐप्लिकेशन टैब पर क्लिक करके, फिर सर्विस वर्कर विकल्प पर क्लिक करके देख सकते हैं कि सर्विस वर्कर रजिस्टर है या नहीं. आपको कुछ ऐसा नज़र आएगा:

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

इसका मतलब है

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

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

सर्विस वर्कर ##39; की स्थिति में बदलाव, सर्विस वर्कर में इवेंट ट्रिगर करते हैं.

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

अपने टेक्स्ट एडिटर में 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 इवेंट का उत्सर्जन करता है. ऊपर दिया गया कोड यहां एक मैसेज लॉग करता है, लेकिन इस इवेंट का इस्तेमाल अक्सर कैश मेमोरी को अपडेट करने के लिए किया जाता है.

किसी दिए गए दायरे के लिए एक बार में सिर्फ़ एक सर्विस वर्कर सक्रिय हो सकता है (सेवा वर्कर का दायरा देखें), इसलिए जब तक कि मौजूदा सर्विस वर्कर का इस्तेमाल न हो जाए, तब तक इंस्टॉल किया हुआ एक सर्विस वर्कर ##39; सक्रिय नहीं रहता है. इसी वजह से किसी सर्विस वर्कर के नियंत्रण वाले सभी पेज, नए कर्मचारी के काम करने से पहले बंद कर देने चाहिए. हमने मौजूदा सर्विस वर्कर का रजिस्ट्रेशन रद्द कर दिया था, इसलिए नए सर्विस वर्कर को तुरंत चालू कर दिया गया था.

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

ध्यान दें: आप कुछ ब्राउज़र' डेवलपर टूल का इस्तेमाल करके, नए सर्विस वर्कर को मैन्युअल तरीके से भी चालू कर सकते हैं. साथ ही, आप 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 एसेट को कैश मेमोरी में सेव किया जा सकता है. अगर ऐसा होता है, तो आपको इन संसाधनों के फ़ेच इवेंट नहीं दिखेंगे.

इसका मतलब है

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

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

प्रतिवाद की आवश्यकताओं

सॉल्यूशन कोड

वर्किंग कोड की कॉपी पाने के लिए, 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() जो वादा करता है वह रजिस्ट्रेशन ऑब्जेक्ट का समाधान करता है, जिसमें सर्विस वर्कर' का दायरा शामिल होता है.

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

सर्विस वर्कर को ले जाएं

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

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

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

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

इसका मतलब है

सर्विस वर्कर ##39; का डिफ़ॉल्ट दायरा सर्विस वर्कर फ़ाइल का पाथ है. सर्विस वर्कर फ़ाइल अब 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 या / जैसे पेजों से नहीं.

ध्यान दें: आप आर्बिट्ररी स्कोप सेट नहीं कर सकते, जो सर्विस वर्कर का #31 हालांकि, अगर आपका सर्वर वर्कर एक Service-Worker-Allowed क्लाइंट के साथ दिखाए जा रहे क्लाइंट पर काम कर रहा है, तो आप सर्विस वर्कर' के स्थान के ऊपर उस सर्विस वर्कर के लिए एक ज़्यादा से ज़्यादा दायरा तय कर सकते हैं.

प्रतिवाद की आवश्यकताओं

सॉल्यूशन कोड

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

अब आपके पास एक साधारण सर्विस वर्कर तैयार है और चल रहा है और सर्विस वर्कर लाइफ़ साइकल को समझ रहा है.

प्रतिवाद की आवश्यकताओं

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

PWA ट्रेनिंग कोर्स में सभी कोडलैब देखने के लिए, आपका स्वागत है