वर्कबॉक्स-विंडो

workbox-window पैकेज, मॉड्यूल का एक सेट है. इसे window कॉन्टेक्स्ट में चलाया जाता है. इसका मतलब है कि इसे आपके वेब पेजों में चलाया जा सकता है. वे सर्विस वर्कर में चलने वाले अन्य वर्कबॉक्स पैकेज के साथ काम करते हैं.

workbox-window की मुख्य सुविधाएं/लक्ष्य ये हैं:

वर्कबॉक्स-विंडो को इंपोर्ट और इस्तेमाल करना

workbox-window पैकेज के लिए मुख्य एंट्री पॉइंट Workbox क्लास है. इसे हमारे सीडीएन से या किसी भी लोकप्रिय JavaScript बंडलिंग टूल का इस्तेमाल करके, अपने कोड में इंपोर्ट किया जा सकता है.

हमारे सीडीएन का इस्तेमाल करके

अपनी साइट पर Workbox क्लास को इंपोर्ट करने का सबसे आसान तरीका, हमारे सीडीएन से है:

<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    wb.register();
  }
</script>

ध्यान दें कि इस उदाहरण में, Workbox क्लास को लोड करने के लिए, <script type="module"> और import स्टेटमेंट का इस्तेमाल किया गया है. ऐसा हो सकता है कि पुराने ब्राउज़र में इस कोड का इस्तेमाल करने के लिए, आपको इसे ट्रांसपाइल करना पड़े. हालांकि, ऐसा करना ज़रूरी नहीं है.

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

JavaScript बंडलर के साथ वर्कबॉक्स लोड किया जा रहा है

workbox-window का इस्तेमाल करने के लिए किसी टूल की ज़रूरत नहीं है. हालांकि, अगर आपके डेवलपमेंट इन्फ़्रास्ट्रक्चर में webpack या Rollup जैसा बंडलर पहले से मौजूद है, जो npm डिपेंडेंसी के साथ काम करता है, तो workbox-window को लोड करने के लिए इनका इस्तेमाल किया जा सकता है.

सबसे पहले, अपने ऐप्लिकेशन की डिपेंडेंसी के तौर पर workbox-window इंस्टॉल करें:

npm install workbox-window

इसके बाद, आपके ऐप्लिकेशन की किसी JavaScript फ़ाइल में, workbox-window पैकेज नाम का रेफ़रंस देते हुए import वर्कबॉक्स:

import {Workbox} from 'workbox-window';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  wb.register();
}

अगर आपके बंडलर में डाइनैमिक इंपोर्ट स्टेटमेंट इस्तेमाल करके कोड को बांटने की सुविधा काम करती है, तो कुछ शर्तों के साथ workbox-window को भी लोड किया जा सकता है. इससे आपके पेज के मुख्य बंडल का साइज़ कम हो जाएगा.

workbox-window बहुत छोटा होने के बावजूद, इसे आपकी साइट के मुख्य ऐप्लिकेशन लॉजिक के साथ लोड करने की ज़रूरत नहीं है. इसकी वजह यह है कि सर्विस वर्कर, अपने स्वभाव में लगातार बेहतर होते हैं.

if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}

बेहतर बंडलिंग सिद्धांत

सर्विस वर्कर में चलने वाले Workbox पैकेज के उलट, package.json में workbox-window के main और module फ़ील्ड से रेफ़र की गई बिल्ड फ़ाइलें ES5 में ट्रांसपिल की जाती हैं. ऐसा करने से, ये आज के बिल्ड टूल के साथ काम करते हैं. इनमें से कुछ टूल, डेवलपर को अपनी node_module डिपेंडेंसी के किसी भी हिस्से को ट्रांसपैर करने की अनुमति नहीं देते हैं.

अगर आपका बिल्ड सिस्टम आपको अपनी डिपेंडेंसी को ट्रांसपाइल करने की अनुमति देता है (या अगर आपको अपने किसी भी कोड को ट्रांसपाइल करने की ज़रूरत नहीं है), तो पैकेज के बजाय किसी खास सोर्स फ़ाइल को इंपोर्ट करना बेहतर है.

यहां Workbox को इंपोर्ट करने के अलग-अलग तरीके दिए गए हैं. साथ ही, यह भी बताया गया है कि हर विकल्प से क्या मिलेगा:

// Imports a UMD version with ES5 syntax
// (pkg.main: "build/workbox-window.prod.umd.js")
const {Workbox} = require('workbox-window');

// Imports the module version with ES5 syntax
// (pkg.module: "build/workbox-window.prod.es5.mjs")
import {Workbox} from 'workbox-window';

// Imports the module source file with ES2015+ syntax
import {Workbox} from 'workbox-window/Workbox.mjs';

उदाहरण

Workbox क्लास इंपोर्ट करने के बाद, इसे रजिस्टर करने और अपने सर्विस वर्कर से इंटरैक्ट करने के लिए इस्तेमाल किया जा सकता है. अपने ऐप्लिकेशन में Workbox का इस्तेमाल करने के कुछ तरीके यहां दिए गए हैं:

सर्विस वर्कर को रजिस्टर करें और पहली बार सर्विस वर्कर के चालू होने पर उपयोगकर्ता को सूचना दें

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

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // `event.isUpdate` will be true if another version of the service
  // worker was controlling the page when this version was registered.
  if (!event.isUpdate) {
    console.log('Service worker activated for the first time!');

    // If your service worker is configured to precache assets, those
    // assets should all be available now.
  }
});

// Register the service worker after event listeners have been added.
wb.register();

अगर सर्विस वर्कर इंस्टॉल हो गया है, लेकिन उसके चालू होने के इंतज़ार में अटक गया है, तो उपयोगकर्ता को सूचना दें

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

इससे डेवलपर को आम तौर पर भ्रम होता है. खास तौर पर, ऐसे मामलों में जहां मौजूदा पेज को फिर से लोड करने से नया सर्विस वर्कर चालू नहीं होता.

भ्रम की स्थिति को कम करने और इस बारे में साफ़ तौर पर बताने के लिए, Workbox क्लास waiting का एक इवेंट उपलब्ध कराती है. आपके पास इस इवेंट को सुनने का विकल्प होता है:

const wb = new Workbox('/sw.js');

wb.addEventListener('waiting', event => {
  console.log(
    `A new service worker has installed, but it can't activate` +
      `until all tabs running the current version have fully unloaded.`
  );
});

// Register the service worker after event listeners have been added.
wb.register();

workbox-broadcast-update पैकेज से कैश मेमोरी अपडेट के बारे में उपयोगकर्ता को सूचना दें

workbox-broadcast-update पैकेज, कैश मेमोरी से कॉन्टेंट दिखाने का एक बेहतरीन तरीका है, ताकि कॉन्टेंट तेज़ी से डिलीवर किया जा सके. साथ ही, इससे उपयोगकर्ता को उस कॉन्टेंट से जुड़े अपडेट के बारे में जानकारी भी मिल सकती है. इसके लिए, पुष्टि करते समय पुरानी रणनीति का इस्तेमाल किया जा सकता है.

विंडो से ये अपडेट पाने के लिए, CACHE_UPDATED टाइप के message इवेंट सुनें:

const wb = new Workbox('/sw.js');

wb.addEventListener('message', event => {
  if (event.data.type === 'CACHE_UPDATED') {
    const {updatedURL} = event.data.payload;

    console.log(`A newer version of ${updatedURL} is available!`);
  }
});

// Register the service worker after event listeners have been added.
wb.register();

सर्विस वर्कर को कैश मेमोरी में सेव किए गए यूआरएल की सूची भेजना

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

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

यह उदाहरण किसी नए सर्विस वर्कर के चालू होने पर, पेज के ज़रिए लोड किए गए यूआरएल की सूची राऊटर को भेजता है. ध्यान दें, सभी यूआरएल भेजना ठीक है, क्योंकि सिर्फ़ सर्विस वर्कर में तय किए गए रूट से मेल खाने वाले यूआरएल कैश मेमोरी में सेव किए जाएंगे:

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // Get the current page URL + all resources the page loaded.
  const urlsToCache = [
    location.href,
    ...performance.getEntriesByType('resource').map(r => r.name),
  ];
  // Send that list of URLs to your router in the service worker.
  wb.messageSW({
    type: 'CACHE_URLS',
    payload: {urlsToCache},
  });
});

// Register the service worker after event listeners have been added.
wb.register();

सर्विस वर्कर की लाइफ़साइकल के अहम पल

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

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

Workbox क्लास, सर्विस वर्कर लाइफ़साइकल के लिए इस आसान व्यू को अपनाती है. इसके लिए, यह सर्विस वर्कर के सभी रजिस्ट्रेशन को दो कैटगरी में बांट देती है: इंस्टेंस का अपना, रजिस्टर किया गया सर्विस वर्कर, और बाहरी सर्विस वर्कर:

  • रजिस्टर किया गया सर्विस वर्कर: ऐसा सर्विस वर्कर जो Workbox इंस्टेंस के register() को कॉल करने या पहले से मौजूद सर्विस वर्कर को कॉल करने के बाद इंस्टॉल होना शुरू हुआ. अगर register() को कॉल करने पर, रजिस्ट्रेशन पर updatefound इवेंट ट्रिगर नहीं होता है, तो सर्विस वर्कर.
  • बाहरी सर्विस वर्कर: ऐसा सर्विस वर्कर जिसने register() को कॉल करने वाले Workbox इंस्टेंस को अलग से इंस्टॉल करना शुरू कर दिया है. आम तौर पर ऐसा तब होता है, जब कोई उपयोगकर्ता आपकी साइट का नया वर्शन किसी दूसरे टैब में खोलता है. जब कोई इवेंट किसी बाहरी सर्विस वर्कर से शुरू होता है, तो इवेंट की isExternal प्रॉपर्टी true पर सेट हो जाएगी.

इन दो तरह के सर्विस वर्कर को ध्यान में रखते हुए, यहां सर्विस वर्कर के सभी अहम लाइफ़साइकल पलों के बारे में बताया गया है. साथ ही, इन्हें मैनेज करने के लिए डेवलपर के सुझाव भी दिए गए हैं:

किसी सर्विस वर्कर को पहली बार इंस्टॉल किए जाने पर

ऐसा हो सकता है कि आप जब पहली बार सर्विस वर्कर इंस्टॉल करें, तो उसके साथ आने वाले सभी अपडेट के साथ अलग तरह से पेश आएं.

workbox-window में, वर्शन को पहले इंस्टॉल करने और आने वाले समय के अपडेट के बीच अंतर करने के लिए, इनमें से किसी भी इवेंट की isUpdate प्रॉपर्टी देखें. पहली बार इंस्टॉल करने पर, isUpdate, false होगा.

const wb = new Workbox('/sw.js');

wb.addEventListener('installed', event => {
  if (!event.isUpdate) {
    // First-installed code goes here...
  }
});

wb.register();
मोमेंट इवेंट सुझाई गई कार्रवाई
किसी नए सर्विस वर्कर को इंस्टॉल किया गया है (पहली बार) installed

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

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

सर्विस वर्कर ने पेज को कंट्रोल करना शुरू कर दिया है controlling

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

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

workbox-window के हिसाब से, इसका मतलब है कि controlling इवेंट सिर्फ़ उन मामलों में भेजा जाता है जहां सर्विस वर्कर clients.claim() को कॉल करता है. अगर पेज को रजिस्ट्रेशन से पहले ही कंट्रोल किया गया है, तो इस इवेंट को नहीं भेजा जाएगा.

सर्विस वर्कर ने चालू कर दिया है activated

जैसा कि ऊपर बताया गया है, जब किसी सर्विस वर्कर को पहली बार चालू करने पर पेज का कंट्रोल शुरू हो जाता है या नहीं होता है, तब ऐसा हो सकता है.

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

सर्विस वर्कर का अपडेट किया गया वर्शन मिलने पर

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

इस स्थिति में आपकी प्रतिक्रिया, आम तौर पर पहली बार इंस्टॉल होने से अलग होती है, क्योंकि आपको यह मैनेज करना होता है कि उपयोगकर्ता को यह अपडेट कब और कैसे मिलेगा.

मोमेंट इवेंट सुझाई गई कार्रवाई
आपने एक नया सर्विस वर्कर इंस्टॉल किया है (पिछला सर्विस वर्कर अपडेट किया जा रहा है) installed

अगर यह पहला सर्विस वर्कर इंस्टॉल (event.isUpdate === true) नहीं है, तो इसका मतलब है कि सर्विस वर्कर का नया वर्शन मिला और इंस्टॉल हो गया है (यह उस वर्शन से अलग है जो फ़िलहाल पेज को कंट्रोल कर रहा है).

आम तौर पर, इसका मतलब है कि साइट का नया वर्शन आपके सर्वर पर डिप्लॉय कर दिया गया है और हो सकता है कि नई ऐसेट ने अभी-अभी प्री-कैशिंग की हो.

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

सर्विस वर्कर इंस्टॉल हो गया है, लेकिन वह इंतज़ार के चरण में है waiting

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

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

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

सर्विस वर्कर ने पेज को कंट्रोल करना शुरू कर दिया है controlling

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

ध्यान दें: अगर आप अपने सर्विस वर्कर में skipWaiting() को कॉल नहीं करते हैं, तो controlling इवेंट सक्रिय नहीं होगा.

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

जब सर्विस वर्कर का कोई ऐसा वर्शन मिलता है जिसकी उम्मीद नहीं थी

कभी-कभी उपयोगकर्ता, आपकी साइट को लंबे समय तक बैकग्राउंड टैब में खुला रखेंगे. वे एक नया टैब खोल सकते हैं और आपकी साइट पर नेविगेट कर सकते हैं. इसके लिए, उन्हें यह पता नहीं चलता कि आपकी साइट पहले से ही किसी बैकग्राउंड टैब में खुली हुई है. ऐसे मामलों में, एक ही समय पर आपकी साइट के दो वर्शन चल सकते हैं. साथ ही, डेवलपर के तौर पर आपको कुछ दिलचस्प समस्याएं आ सकती हैं.

ऐसे मामले पर विचार करें जिसमें आपकी साइट का टैब A चल रहा v1 हो और टैब B चल रहा हो v2. टैब B लोड होने पर, इसे आपके सेवा देने वाले का वह वर्शन कंट्रोल करेगा जो v1 से शिप किया गया है. हालांकि, सर्वर (अगर आपने नेविगेशन अनुरोधों के लिए नेटवर्क-फ़र्स्ट कैश मेमोरी का इस्तेमाल कर रहे हैं) जो पेज दिखाता है, तो उसमें आपकी सभी v2 एसेट होंगी.

हालांकि, आम तौर पर टैब B के लिए यह समस्या नहीं होती, क्योंकि जब आपने अपना v2 कोड लिखा था, तब आपको पता था कि आपका v1 कोड कैसे काम करता है. हालांकि, यह टैब A के लिए समस्या हो सकती है, क्योंकि आपके v1 कोड से यह अंदाज़ा नहीं लगाया जा सकता कि आपके v2 कोड में क्या बदलाव होंगे.

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

Workbox v6 और उसके बाद के वर्शन के हिसाब से, ये इवेंट ऊपर दर्ज किए गए इवेंट के जैसे होते हैं. साथ ही, हर इवेंट ऑब्जेक्ट पर एक isExternal: true प्रॉपर्टी सेट होती है. अगर आपके वेब ऐप्लिकेशन को किसी "बाहरी" सर्विस वर्कर को मैनेज करने के लिए किसी खास लॉजिक को लागू करने की ज़रूरत है, तो अपने इवेंट हैंडलर में उस प्रॉपर्टी को देखें.

आम गलतियों से बचना

Workbox की सबसे ज़्यादा मददगार सुविधाओं में से एक यह है कि इसकी डेवलपर लॉगिंग है. यह खास तौर पर, workbox-window पर लागू होता है.

हम जानते हैं कि सर्विस वर्कर के साथ काम करना अक्सर भ्रम की स्थिति पैदा करता है. जब चीज़ें आपकी उम्मीद से उलट होती हैं, तो इसकी वजह जानना मुश्किल हो सकता है.

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

हालांकि, किसी सर्विस वर्कर को Workbox क्लास में रजिस्टर करने पर, आपको डेवलपर कंसोल में लाइफ़साइकल की स्थिति में हुए सभी बदलावों के बारे में जानकारी दी जाएगी. इससे, आपको उम्मीद के मुताबिक चीज़ें क्यों नहीं हो रही हैं, इसे डीबग करने में मदद मिलेगी.

इंतज़ार कर रहे वर्कर के लिए वर्कबॉक्स-विंडो कंसोल से जुड़ी चेतावनी

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

इसे रोकने में मदद करने के लिए, अगर सर्विस वर्कर को रजिस्टर करने वाला पेज उस सर्विस वर्कर के दायरे में नहीं है, तो Workbox क्लास आपको चेतावनी देगी. यह उन मामलों में भी आपको चेतावनी देगी जहां आपका सर्विस वर्कर चालू है, लेकिन अभी तक पेज को कंट्रोल नहीं कर रहा है:

उसे कंट्रोल न करने वाले वर्कर के लिए वर्कबॉक्स-विंडो कंसोल से जुड़ी चेतावनी

सर्विस वर्कर कम्यूनिकेशन के लिए विंडो

सबसे बेहतर सर्विस वर्कर के इस्तेमाल में, सर्विस वर्कर और विंडो के बीच बहुत सारे मैसेज होते हैं. इसमें Workbox क्लास भी मदद करती है. इसके लिए, messageSW() वाला तरीका उपलब्ध कराएं. इससे, इंस्टेंस का रजिस्टर किया गया सर्विस वर्कर postMessage() हो जाएगा और जवाब का इंतज़ार किया जाएगा.

सर्विस वर्कर को किसी भी फ़ॉर्मैट में डेटा भेजा जा सकता है. हालांकि, सभी वर्कबॉक्स पैकेज के साथ शेयर किया गया फ़ॉर्मैट, तीन प्रॉपर्टी वाला एक ऑब्जेक्ट होता है (दूसरा दो विकल्प नहीं होता):

प्रॉपर्टी ज़रूरी है? टाइप ब्यौरा
type हां string

इस मैसेज को पहचानने वाली एक यूनीक स्ट्रिंग.

शर्त के मुताबिक, टाइप में अंग्रेज़ी के सभी टाइप अपरकेस में होते हैं और अंडरस्कोर में शब्दों को अलग-अलग रखा जाता है. अगर टाइप किसी कार्रवाई को दिखाता है, तो यह वर्तमान काल (जैसे कि CACHE_URLS) में एक निर्देश होना चाहिए. अगर टाइप, रिपोर्ट की जा रही जानकारी को दिखाता है, तो यह पास्ट टेंस में होना चाहिए (जैसे, URLS_CACHED).

meta no string Workbox में, यह हमेशा मैसेज भेजने वाले Workbox पैकेज का नाम होता है. खुद मैसेज भेजते समय, इस प्रॉपर्टी को छोड़ा जा सकता है या इसे अपनी पसंद के मुताबिक सेट किया जा सकता है.
payload no * भेजा जा रहा डेटा. आम तौर पर, यह एक ऑब्जेक्ट है, लेकिन ज़रूरी नहीं है कि ऐसा हो.

messageSW() तरीके से भेजे गए मैसेज MessageChannel का इस्तेमाल करते हैं, ताकि फ़ाइल पाने वाला व्यक्ति उन मैसेज का जवाब दे सके. किसी मैसेज का जवाब देने के लिए, मैसेज इवेंट लिसनर में event.ports[0].postMessage(response) को कॉल किया जा सकता है. messageSW() तरीके से ऐसा प्रॉमिस मिलता है जो response के जवाब के साथ-साथ पूरी तरह मेल खाता है.

यहां विंडो से सर्विस वर्कर को मैसेज भेजने और वापस जवाब पाने का उदाहरण दिया गया है. पहला कोड ब्लॉक, सर्विस वर्कर में मैसेज लिसनर है. दूसरा ब्लॉक, मैसेज भेजने और रिस्पॉन्स का इंतज़ार करने के लिए Workbox क्लास का इस्तेमाल करता है:

sw.js में कोड:

const SW_VERSION = '1.0.0';

addEventListener('message', event => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

main.js में मौजूद कोड (विंडो में चल रहा है):

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

वर्शन के साथ काम न करने वाले वर्शन को मैनेज करना

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

नेटवर्क पहले

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

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

इस वजह से, कोई भी ज़रूरी काम करने से पहले बेहतर है कि आप अपने सर्विस वर्कर का वर्शन बना लें और उनके साथ काम करने वाले वर्शन की जांच कर लें.

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

पहले कैश मेमोरी में सेव करें

पेजों को नेटवर्क-फ़र्स्ट में दिखाने की जगह, पेजों को कैश मेमोरी में सबसे पहले दिखाते समय, आपको पता होता है कि शुरुआत में आपका पेज और आपके सर्विस वर्कर का वर्शन एक ही रहेगा. ऐसा इसलिए, क्योंकि इसे वही वर्शन दिखाता है. इस वजह से, messageSW() का तुरंत इस्तेमाल करना सुरक्षित है.

हालांकि, अगर आपके पेज पर register() को कॉल करने पर, आपके सर्विस वर्कर का अपडेट किया हुआ वर्शन मिलता है और यह चालू हो जाता है (जैसे, आपने जान-बूझकर इंतज़ार का चरण छोड़ दिया), तो उस पर मैसेज भेजना सुरक्षित नहीं होगा.

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

इंतज़ार करने का समय छोड़ें

विंडो से सर्विस वर्कर मैसेजिंग तक पहुंचने के लिए, एक सामान्य इस्तेमाल के तौर पर {type: 'SKIP_WAITING'} मैसेज भेजा जाता है. इस मैसेज में, इंस्टॉल किए गए सर्विस वर्कर को इंतज़ार का चरण छोड़ने और चालू करने के लिए कहा जाता है.

Workbox v6 से शुरू करते हुए, मौजूदा सर्विस वर्कर रजिस्ट्रेशन से जुड़े इंतज़ार करने वाले सर्विस वर्कर को {type: 'SKIP_WAITING'} मैसेज भेजने के लिए, messageSkipWaiting() तरीके का इस्तेमाल किया जा सकता है. अगर कोई सर्विस वर्कर नहीं जाएगा, तो यह चुपचाप कुछ नहीं करेगा.

टाइप

Workbox

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

प्रॉपर्टी

  • कंस्ट्रक्टर

    void

    स्क्रिप्ट यूआरएल और सर्विस वर्कर विकल्पों के साथ एक नया Workbox इंस्टेंस बनाता है. स्क्रिप्ट यूआरएल और विकल्प वही होते हैं जिनका इस्तेमाल navigator.serviceWorker.register(scriptURL, options) को कॉल करते समय इस्तेमाल किया जाता है.

    constructor फ़ंक्शन ऐसा दिखता है:

    (scriptURL: string|TrustedScriptURL,registerOptions?: object)=> {...}

    • scriptURL

      स्ट्रिंग|TrustedScriptURL

      इस इंस्टेंस से जुड़ी सर्विस वर्कर स्क्रिप्ट. TrustedScriptURL का इस्तेमाल किया जा सकता है.

    • registerOptions

      ऑब्जेक्ट ज़रूरी नहीं

  • सक्रिय

    Promise<ServiceWorker>

  • कंट्रोल कर रही हूँ

    Promise<ServiceWorker>

  • getSW

    void

    इस इंस्टेंस के स्क्रिप्ट यूआरएल से मेल खाने वाले सर्विस वर्कर के रेफ़रंस के साथ, जैसे ही यह उपलब्ध होता है, यह रिज़ॉल्व हो जाता है.

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

    getSW फ़ंक्शन ऐसा दिखता है:

    ()=> {...}

    • returns

      Promise<ServiceWorker>

  • messageSW

    void

    पास किए गए डेटा ऑब्जेक्ट को इस इंस्टेंस (workbox-window.Workbox#getSW के ज़रिए) से रजिस्टर किए गए सर्विस वर्कर को भेजता है और रिस्पॉन्स (अगर कोई है) के साथ उसका समाधान करता है.

    सर्विस वर्कर में मैसेज हैंडलर में, event.ports[0].postMessage(...) को कॉल करके रिस्पॉन्स सेट किया जा सकता है. इससे messageSW() से मिले प्रॉमिस का समाधान हो जाएगा. अगर कोई प्रतिक्रिया सेट नहीं है, तो प्रॉमिस कभी भी हल नहीं होगी.

    messageSW फ़ंक्शन ऐसा दिखता है:

    (data: object)=> {...}

    • डेटा

      ऑब्जेक्ट

      सर्विस वर्कर को भेजने के लिए कोई ऑब्जेक्ट

    • returns

      वादा<any>

  • messageSkipWaiting

    void

    यह उस सर्विस वर्कर को {type: 'SKIP_WAITING'} मैसेज भेजता है जो फ़िलहाल मौजूदा रजिस्ट्रेशन से जुड़े waiting स्थिति में है.

    अगर मौजूदा रजिस्ट्रेशन नहीं है या कोई सर्विस वर्कर waiting नहीं है, तो इसे कॉल करने से कोई असर नहीं पड़ेगा.

    messageSkipWaiting फ़ंक्शन ऐसा दिखता है:

    ()=> {...}

  • register

    void

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

    register फ़ंक्शन ऐसा दिखता है:

    (options?: object)=> {...}

    • विकल्प

      ऑब्जेक्ट ज़रूरी नहीं

      • यहीं पास में कहीं

        बूलियन ज़रूरी नहीं

    • returns

      Promise<ServiceWorkerRegistration>

  • अपडेट करो

    void

    रजिस्टर किए गए सर्विस वर्कर के अपडेट की जांच करता है.

    update फ़ंक्शन ऐसा दिखता है:

    ()=> {...}

    • returns

      Promise<void>

WorkboxEventMap

प्रॉपर्टी

WorkboxLifecycleEvent

प्रॉपर्टी

  • isExternal

    बूलियन ज़रूरी नहीं

  • isUpdate

    बूलियन ज़रूरी नहीं

  • originalEvent

    इवेंट ज़रूरी नहीं

  • sw

    ServiceWorker ज़रूरी नहीं

  • टारगेट

    WorkboxEventTarget ज़रूरी नहीं

  • टाइप

    typeOperator

WorkboxLifecycleEventMap

प्रॉपर्टी

WorkboxLifecycleWaitingEvent

प्रॉपर्टी

  • isExternal

    बूलियन ज़रूरी नहीं

  • isUpdate

    बूलियन ज़रूरी नहीं

  • originalEvent

    इवेंट ज़रूरी नहीं

  • sw

    ServiceWorker ज़रूरी नहीं

  • टारगेट

    WorkboxEventTarget ज़रूरी नहीं

  • टाइप

    typeOperator

  • wasWaitingBeforeRegister

    बूलियन ज़रूरी नहीं

WorkboxMessageEvent

प्रॉपर्टी

  • डेटा

    कोई भी

  • isExternal

    बूलियन ज़रूरी नहीं

  • originalEvent

    इवेंट

  • ports

    typeOperator

  • sw

    ServiceWorker ज़रूरी नहीं

  • टारगेट

    WorkboxEventTarget ज़रूरी नहीं

  • टाइप

तरीके

messageSW()

workbox-window.messageSW(
  sw: ServiceWorker,
  data: object,
)

यह postMessage के ज़रिए किसी सर्विस वर्कर को डेटा ऑब्जेक्ट भेजता है. साथ ही, रिस्पॉन्स (अगर कोई है) के साथ रिज़ॉल्व करता है.

सर्विस वर्कर में मैसेज हैंडलर में, event.ports[0].postMessage(...) को कॉल करके रिस्पॉन्स सेट किया जा सकता है. इससे messageSW() से मिले प्रॉमिस का समाधान हो जाएगा. अगर कोई जवाब सेट नहीं है, तो प्रॉमिस हल नहीं होगा.

पैरामीटर

  • sw

    ServiceWorker

    सर्विस वर्कर, जिसे मैसेज भेजना है.

  • डेटा

    ऑब्जेक्ट

    सर्विस वर्कर को भेजने के लिए कोई ऑब्जेक्ट.

रिटर्न

  • वादा<any>