Workbox v4 से v5 पर माइग्रेट करें

इस गाइड में, Workbox v5 में हुए बदलावों के बारे में जानकारी दी गई है. साथ ही, यह बताया गया है कि वर्कबॉक्स v4 से अपग्रेड करते समय आपको क्या-क्या बदलाव करने होंगे.

नुकसान पहुंचा सकने वाले बदलाव

प्लग इन क्लास का नाम बदला गया

कई Workbox v4 पैकेज में Plugin नाम की क्लास शामिल हैं. v5 में, उन क्लास के नाम बदल दिए गए हैं, ताकि पैकेज आइडेंटिफ़ायर + Plugin पैटर्न को फ़ॉलो किया जा सके:

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

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

डिफ़ॉल्ट प्रीकैश मेनिफ़ेस्ट रीप्लेसमेंट पॉइंट

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

Workbox v5 में, बदलाव करने का लॉजिक बदल गया है. अब self.__WB_MANIFEST का इस्तेमाल, इंजेक्शन पॉइंट के तौर पर डिफ़ॉल्ट रूप से किया जाता है.

// v4:
precacheAndRoute([]);

// v5:
precacheAndRoute(self.__WB_MANIFEST);

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

नेविगेशन के रास्तों के लिए पहले इस्तेमाल किए जाने वाले दो विकल्पों, blacklist और whitelist का नाम बदलकर denylist और allowlist कर दिया गया है.

workbox-routing पर पहले registerNavigationRoute() नाम का एक तरीका काम करता था. यह तरीका, अंदरूनी तौर पर दो काम करता था:

  1. पता लगाया गया कि दिए गए fetch इवेंट में, mode 'navigate' था या नहीं.
  2. अगर हां, तो पहले कैश मेमोरी में सेव किए गए, हार्डकोड किए गए यूआरएल के कॉन्टेंट का इस्तेमाल करके, उस अनुरोध का जवाब दिया गया था. भले ही, यूआरएल को नेविगेट किया जा रहा हो.

यह एक सामान्य पैटर्न है, जिसका इस्तेमाल ऐप्लिकेशन शेल आर्किटेक्चर लागू करते समय किया जाता है.

दूसरा चरण, कैश मेमोरी से पढ़कर रिस्पॉन्स जनरेट करना, workbox-routing की ज़िम्मेदारियों के दायरे से बाहर है. इसके बजाय, हम इसे एक ऐसी सुविधा के तौर पर देखते हैं जिसे createHandlerBoundToURL() के नए तरीके से workbox-precaching का हिस्सा बनाया जाना चाहिए. यह नया तरीका, workbox-routing में मौजूद NavigationRoute क्लास के साथ मिलकर काम कर सकता है, ताकि यही लॉजिक पूरा किया जा सके.

अगर बिल्ड टूल के "generate SW" मोड में से किसी एक में navigateFallback विकल्प का इस्तेमाल किया जा रहा है, तो स्विचओवर अपने-आप हो जाएगा. अगर आपने पहले navigateFallbackBlacklist या navigateFallbackWhitelist विकल्पों को कॉन्फ़िगर किया है, तो उन्हें क्रमशः navigateFallbackDenylist या navigateFallbackAllowlist में बदलें.

अगर " मेनिफ़ेस्ट इंजेक्ट" का इस्तेमाल किया जा रहा है, तो मोड का इस्तेमाल करना होगा या बस सर्विस वर्कर को खुद लिखना होगा और आपका Workbox v4 सर्विस वर्कर registerNavigationRoute() को सीधे कॉल करेगा, तो आपको इसके जैसा व्यवहार पाने के लिए अपने कोड में बदलाव करना होगा.

// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';

const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
  whitelist: [...],
  blacklist: [...],
});

// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';

const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
  allowlist: [...],
  denylist: [...],
});
registerRoute(navigationRoute);

अब आपको getCacheKeyForURL() को कॉल करने की ज़रूरत नहीं है, क्योंकि createHandlerBoundToURL() आपके लिए इसका ध्यान रखेगा.

वर्कबॉक्स-रणनीतियों से MakeRequest() को हटाना

makeRequest() को कॉल करना, ज़्यादातर मामलों में workbox-strategy क्लास में से किसी एक पर handle() को कॉल करने के बराबर होता है. दोनों के बीच अंतर इतना छोटा था कि दोनों को रखने का कोई मतलब नहीं था. makeRequest() को कॉल करने वाले डेवलपर, बिना किसी बदलाव के handle() का इस्तेमाल कर पाएंगे:

// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});

// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});

v5 में, handle() request को ज़रूरी पैरामीटर मानता है और event.request का इस्तेमाल नहीं करेगा. handle() पर कॉल करते समय, पक्का करें कि आपने मान्य अनुरोध पास किया हो.

workbox-broadcast-update हमेशा postMessage() का इस्तेमाल करता है

v4 में, workbox-broadcast-update लाइब्रेरी काम न करने पर मैसेज भेजने के लिए, डिफ़ॉल्ट रूप से ब्रॉडकास्ट चैनल एपीआई का इस्तेमाल करेगी. साथ ही, postMessage() का इस्तेमाल सिर्फ़ तब होगा, जब ब्रॉडकास्ट चैनल काम नहीं करता हो.

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

इसी वजह से, हमने workbox-broadcast-update को बदलकर, v5 में हमेशा postMessage() का इस्तेमाल किया है. मौजूदा सर्विस वर्कर के दायरे में आने वाले सभी क्लाइंट पेजों पर, मैसेज एक-एक करके भेजे जाते हैं.

इस नए व्यवहार को लागू करने के लिए, क्लाइंट पेजों में मौजूद वह कोड हटाया जा सकता है जिसने BroadcastChannel इंस्टेंस बनाए हैं. इसके बजाय, navigator.serviceWorker पर message इवेंट लिसनर सेट अप करें:

// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
  const {cacheName, updatedUrl} = event.data.payload;
  // ... your code here ...
});

// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
  // Optional: ensure the message came from workbox-broadcast-update
  if (event.meta === 'workbox-broadcast-update') {
    const {cacheName, updatedUrl} = event.data.payload;
    // ... your code here ...
  }
});

workbox-window के उपयोगकर्ताओं को कोई बदलाव करने की ज़रूरत नहीं है, क्योंकि postMessage() कॉल को सुनने के लिए, इसके इंटरनल लॉजिक को अपडेट कर दिया गया है.

बिल्ड टूल के लिए Node.js v8 या इसके बाद का वर्शन होना ज़रूरी है

Node.js के v8 से पहले के वर्शन, अब workbox-webpack-plugin, workbox-build या workbox-cli के साथ काम नहीं करते. अगर आपके पास Node.js का 8 से पहले का वर्शन है, तो अपने रनटाइम को काम करने वाले वर्शन पर अपडेट करें.

workbox-webpack-plugin के लिए, webpack v4 या इसके बाद के वर्शन की ज़रूरत है

अगर workbox-webpack-plugin का इस्तेमाल किया जा रहा है, तो कम से कम webpack v4 का इस्तेमाल करने के लिए, अपना webpack सेटअप अपडेट करें.

बिल्ड टूल के विकल्पों में काफ़ी बदलाव

कई workbox-build, workbox-cli, और workbox-webpack-plugin कॉन्फ़िगरेशन पैरामीटर अब काम नहीं करते. उदाहरण के लिए, generateSW आपके लिए हमेशा एक लोकल वर्कबॉक्स रनटाइम बंडल बनाएगा, इसलिए importWorkboxFrom विकल्प का कोई मतलब नहीं रहेगा.

इस्तेमाल किए जा सकने वाले विकल्पों की सूची के लिए, उस टूल के दस्तावेज़ देखें.

workbox-build से generateSWString को हटाना

generateSWString मोड को workbox-build से हटा दिया गया है. हमें उम्मीद है कि इसका असर बहुत कम होगा, क्योंकि इसे मुख्य रूप से workbox-webpack-plugin ने अंदरूनी तौर पर इस्तेमाल किया था.

वैकल्पिक बदलाव

मॉड्यूल इंपोर्ट का इस्तेमाल करना

हालांकि, यह बदलाव a) ज़रूरी नहीं है और b) Workbox v4 के इस्तेमाल के दौरान तकनीकी रूप से संभव था, लेकिन वर्शन 5 का इस्तेमाल करते समय हमें सबसे बड़ा बदलाव देखने को मिल सकता था. यह ऐसा मॉडल है जिसमें वर्कबॉक्स के मॉड्यूल इंपोर्ट करके, बंडल किए गए सर्विस वर्कर बनाए जाते हैं. यह तरीका, आपके सेवा वर्कर में सबसे ऊपर importScripts('/path/to/workbox-sw.js') को कॉल करने और workbox.* नेमस्पेस के ज़रिए Workbox का इस्तेमाल करने का विकल्प है.

अगर "Generate SW" में किसी बिल्ड टूल (workbox-webpack-plugin, workbox-build, workbox-cli) का इस्तेमाल किया जा रहा है मोड बंद करते हैं, तो यह बदलाव आपके लिए अपने-आप हो जाएगा. ये सभी टूल, आपके सेवा वर्कर लॉजिक को लागू करने के लिए ज़रूरी कोड के साथ-साथ, Workbox रनटाइम का एक स्थानीय, कस्टम बंडल आउटपुट करेंगे. इस स्थिति में, अब workbox-sw या Workbox की सीडीएन कॉपी पर कोई डिपेंडेंसी नहीं है. आपके inlineWorkboxRuntime कॉन्फ़िगरेशन की वैल्यू के आधार पर, Workbox रनटाइम को एक अलग फ़ाइल में बांटा जाएगा. इसे आपके सेवा वर्कर के साथ डिप्लॉय किया जाना चाहिए (false पर सेट होने पर, जो डिफ़ॉल्ट है) या सेवा वर्कर लॉजिक के साथ इनलाइन शामिल किया जाना चाहिए (true पर सेट होने पर).

अगर "मैनिफ़ेस्ट इंजेक्ट करें" मोड में बिल्ड टूल का इस्तेमाल किया जा रहा है या Workbox के बिल्ड टूल का इस्तेमाल नहीं किया जा रहा है, तो Workbox के साथ बंडलर (webpack/Rollup) का इस्तेमाल करना गाइड में जाकर, अपना Workbox रनटाइम बंडल बनाने के बारे में ज़्यादा जानें.

v5 के दस्तावेज़ और उदाहरण यह मानकर लिखे गए हैं कि मॉड्यूल इंपोर्ट सिंटैक्स का इस्तेमाल करता है. हालांकि, वर्कबॉक्स v5 के साथ workbox.* नेमस्पेस काम करता रहेगा.

पहले से कैश मेमोरी में सेव किए गए जवाब पढ़ना

कुछ डेवलपर को, पहले से कैश मेमोरी में सेव किए गए जवाबों को precacheAndRoute() तरीके से इस्तेमाल करने के बजाय, सीधे कैश मेमोरी से पढ़ना पड़ता है. v4 में एक सामान्य पैटर्न यह होगा कि पहले पहले से कैश मेमोरी में सेव किए गए संसाधन के मौजूदा वर्शन के लिए कैश की, खास कुंजी पाएं. इसके बाद, Response पाने के लिए, उस कुंजी को पहले से कैश मेमोरी में सेव किए गए संसाधन के कैश मेमोरी के नाम के साथ caches.match() में पास करें.

इस प्रोसेस को आसान बनाने के लिए, v5 में workbox-precaching, matchPrecache() नाम के नए और मिलते-जुलते तरीके का इस्तेमाल करता है:

// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';

const cachedResponse = await caches.match(
  getCacheKeyForURL(`/somethingPrecached`),
  {
    cacheName: cacheNames.precache,
  }
);

// v5:
import {matchPrecache} from 'workbox-precaching';

const cachedResponse = await matchPrecache(`/somethingPrecached`);

TypeScript अपनाना

v5 में, Workbox रनटाइम लाइब्रेरी TypeScript में लिखी जाती हैं. हम TypeScript का इस्तेमाल न करने वाले डेवलपर के लिए, ट्रांसपाइल किए गए JavaScript मॉड्यूल और बंडल पब्लिश करते रहेंगे. हालांकि, अगर TypeScript का इस्तेमाल किया जा रहा है, तो आपको सीधे Workbox प्रोजेक्ट से, सटीक और हमेशा अप-टू-डेट टाइप की जानकारी मिल सकती है.

माइग्रेशन का उदाहरण

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

हालांकि, इसमें नुकसान पहुंचाने वाले हर बदलाव को शामिल नहीं किया गया है, लेकिन यहां एक सर्विस वर्कर फ़ाइल को v4 से v5 में अपग्रेड करने के पहले और बाद के बारे में बताया गया है. इसमें TypeScript पर स्विच करने का तरीका भी बताया गया है.

मदद लेना

हमें उम्मीद है कि ज़्यादातर माइग्रेशन आसानी से हो जाएंगे. अगर आपको ऐसी समस्याएं आती हैं जिनके बारे में इस गाइड में नहीं बताया गया है, तो GitHub पर शिकायत करें.