सर्विस वर्कर के साथ इवेंट मैनेज करना

एक्सटेंशन सर्विस वर्कर के कॉन्सेप्ट को शामिल करने वाला ट्यूटोरियल

खास जानकारी

यह ट्यूटोरियल Chrome एक्सटेंशन सर्विस वर्कर के बारे में जानकारी देता है. इस ट्यूटोरियल के तौर पर, आप एक ऐसा एक्सटेंशन बनाएंगे जिससे उपयोगकर्ता खोज वाली पट्टी का इस्तेमाल करके, Chrome API के रेफ़रंस पेजों पर तेज़ी से नेविगेट कर पाएंगे. आपको, इनके बारे में जानकारी मिलेगी:

  • अपने सर्विस वर्कर को रजिस्टर करें और मॉड्यूल इंपोर्ट करें.
  • अपने एक्सटेंशन सर्विस वर्कर को डीबग करें.
  • स्थिति और इवेंट मैनेज करें.
  • समय-समय पर होने वाले इवेंट ट्रिगर करें.
  • कॉन्टेंट स्क्रिप्ट का इस्तेमाल करके बातचीत करना.

शुरू करने से पहले

इस गाइड में यह माना गया है कि आपके पास वेब डेवलपमेंट का बुनियादी अनुभव है. एक्सटेंशन डेवलपमेंट के बारे में जानकारी पाने के लिए, हम आपको एक्सटेंशन 101 और Hello World की समीक्षा करने का सुझाव देते हैं.

एक्सटेंशन बनाएं

एक्सटेंशन फ़ाइलों को होल्ड करने के लिए, quick-api-reference नाम की नई डायरेक्ट्री बनाकर शुरुआत करें या GitHub के सैंपल रिपॉज़िटरी से सोर्स कोड डाउनलोड करें.

पहला चरण: सर्विस वर्कर को रजिस्टर करें

प्रोजेक्ट के रूट में मेनिफ़ेस्ट फ़ाइल बनाएं और यह कोड जोड़ें:

manifest.json:

{
  "manifest_version": 3,
  "name": "Open extension API reference",
  "version": "1.0.0",
  "icons": {
    "16": "images/icon-16.png",
    "128": "images/icon-128.png"
  },
  "background": {
    "service_worker": "service-worker.js",
  },
}

एक्सटेंशन, अपने सर्विस वर्कर को मेनिफ़ेस्ट में रजिस्टर करते हैं. मेनिफ़ेस्ट फ़ाइल में सिर्फ़ एक JavaScript फ़ाइल का इस्तेमाल किया जा सकता है. आपको navigator.serviceWorker.register() को कॉल करने की ज़रूरत नहीं है, जैसा कि आप किसी वेब पेज पर करते हैं.

एक images फ़ोल्डर बनाएं. इसके बाद, उसमें आइकॉन डाउनलोड करें.

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

दूसरा चरण: एक से ज़्यादा सर्विस वर्कर मॉड्यूल इंपोर्ट करना

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

manifest.json:

{
 "background": {
    "service_worker": "service-worker.js",
    "type": "module"
  },
}

service-worker.js फ़ाइल बनाएं और दो मॉड्यूल इंपोर्ट करें:

import './sw-omnibox.js';
import './sw-tips.js';

इन फ़ाइलों को बनाएं और हर फ़ाइल में कंसोल लॉग जोड़ें.

sw-omnibox.js:

console.log("sw-omnibox.js")

sw-tips.js:

console.log("sw-tips.js")

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

ज़रूरी नहीं: सर्विस वर्कर को डीबग करना

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

30 सेकंड बाद आपको "सर्विस वर्कर (इनऐक्टिव)" दिखेगा. इसका मतलब है कि सर्विस वर्कर बंद कर दिया गया है. इसकी जांच करने के लिए, "सर्विस वर्कर (इस्तेमाल में नहीं है)" लिंक पर क्लिक करें. नीचे दिए गए ऐनिमेशन में यह दिखाया गया है.

क्या आपने देखा कि सर्विस वर्कर की जांच करने पर वह जाग गया? DevTools में सर्विस वर्कर खोलने पर, यह चालू रहेगा. यह पक्का करने के लिए कि आपके सर्विस वर्कर को बंद किए जाने के बाद आपका एक्सटेंशन ठीक से काम करता है, DevTools बंद करना न भूलें.

अब, एक्सटेंशन को ब्रेक करके जानें कि गड़बड़ियों का पता कहां लगाना है. ऐसा करने का एक तरीका यह है कि आप service-worker.js फ़ाइल के './sw-omnibox.js' इंपोर्ट से ".js" को मिटाएं. Chrome, सर्विस वर्कर को रजिस्टर नहीं कर पाएगा.

chrome://extensions पर वापस जाएं और एक्सटेंशन को रीफ़्रेश करें. आपको दो गड़बड़ियां दिखेंगी:

Service worker registration failed. Status code: 3.

An unknown error occurred when fetching the script.

एक्सटेंशन सर्विस वर्कर को डीबग करने के ज़्यादा तरीकों के लिए, एक्सटेंशन डीबग करना देखें.

चौथा चरण: स्टेट शुरू करना

अगर सर्विस वर्कर की ज़रूरत नहीं होगी, तो Chrome उन्हें बंद कर देगा. हम सभी सर्विस वर्कर सेशन में एक जैसी स्थिति बनाए रखने के लिए, chrome.storage एपीआई का इस्तेमाल करते हैं. स्टोरेज का ऐक्सेस पाने के लिए, हमें मेनिफ़ेस्ट में अनुमति का अनुरोध करना होगा:

manifest.json:

{
  ...
  "permissions": ["storage"],
}

सबसे पहले, डिफ़ॉल्ट सुझावों को स्टोरेज में सेव करें. हम runtime.onInstalled() इवेंट को सुनकर, एक्सटेंशन पहली बार इंस्टॉल होने की स्थिति शुरू कर सकते हैं:

sw-omnibox.js:

...
// Save default API suggestions
chrome.runtime.onInstalled.addListener(({ reason }) => {
  if (reason === 'install') {
    chrome.storage.local.set({
      apiSuggestions: ['tabs', 'storage', 'scripting']
    });
  }
});

सर्विस वर्कर के पास विंडो ऑब्जेक्ट का सीधे तौर पर ऐक्सेस नहीं होता है. इसलिए, वे वैल्यू स्टोर करने के लिए, window.localStorage का इस्तेमाल नहीं कर सकते. साथ ही, सर्विस वर्कर कुछ समय तक चलने वाले एक्ज़ीक्यूशन एनवायरमेंट होते हैं. उपयोगकर्ता के पूरे ब्राउज़र सेशन के दौरान उन्हें बार-बार खत्म किया जाता है. इस वजह से वे ग्लोबल वैरिएबल के साथ काम नहीं करते. इसके बजाय, chrome.storage.local का इस्तेमाल करें. यह लोकल मशीन पर डेटा सेव करता है.

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

पांचवां चरण: अपने इवेंट रजिस्टर करें

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

इस उदाहरण में, हम chrome.omnibox एपीआई का इस्तेमाल करेंगे, लेकिन पहले हमें मेनिफ़ेस्ट में खोज वाली पट्टी कीवर्ड ट्रिगर के बारे में बताना होगा:

manifest.json:

{
  ...
  "minimum_chrome_version": "102",
  "omnibox": {
    "keyword": "api"
  },
}

अब, स्क्रिप्ट के शीर्ष स्तर पर खोज बार वाले इवेंट लिसनर को रजिस्टर करें. जब उपयोगकर्ता पता बार में टैब या स्पेस के बाद खोज बार वाला कीवर्ड (api) डालता है, तो Chrome स्टोरेज में मौजूद कीवर्ड के आधार पर सुझावों की सूची दिखाएगा. इन सुझावों को अपने-आप भरने के लिए, onInputChanged() इवेंट की ज़िम्मेदारी होती है. यह इवेंट, उपयोगकर्ता के मौजूदा इनपुट और suggestResult ऑब्जेक्ट को लेता है.

sw-omnibox.js:

...
const URL_CHROME_EXTENSIONS_DOC =
  'https://developer.chrome.com/docs/extensions/reference/';
const NUMBER_OF_PREVIOUS_SEARCHES = 4;

// Display the suggestions after user starts typing
chrome.omnibox.onInputChanged.addListener(async (input, suggest) => {
  await chrome.omnibox.setDefaultSuggestion({
    description: 'Enter a Chrome API or choose from past searches'
  });
  const { apiSuggestions } = await chrome.storage.local.get('apiSuggestions');
  const suggestions = apiSuggestions.map((api) => {
    return { content: api, description: `Open chrome.${api} API` };
  });
  suggest(suggestions);
});

जब उपयोगकर्ता कोई सुझाव चुनता है, तो उससे जुड़ा Chrome API का रेफ़रंस पेज onInputEntered() खुल जाएगा.

sw-omnibox.js:

...
// Open the reference page of the chosen API
chrome.omnibox.onInputEntered.addListener((input) => {
  chrome.tabs.create({ url: URL_CHROME_EXTENSIONS_DOC + input });
  // Save the latest keyword
  updateHistory(input);
});

updateHistory() फ़ंक्शन, खोज वाली पट्टी का इनपुट लेता है और उसे storage.local पर सेव करता है. इस तरह से खोज के लिए सबसे हाल के शब्द का इस्तेमाल, बाद में खोज वाली पट्टी के सुझाव के तौर पर किया जा सकता है.

sw-omnibox.js:

...
async function updateHistory(input) {
  const { apiSuggestions } = await chrome.storage.local.get('apiSuggestions');
  apiSuggestions.unshift(input);
  apiSuggestions.splice(NUMBER_OF_PREVIOUS_SEARCHES);
  return chrome.storage.local.set({ apiSuggestions });
}

छठा चरण: बार-बार होने वाला इवेंट सेट अप करना

आम तौर पर, setTimeout() या setInterval() तरीकों का इस्तेमाल, देरी से किए जाने वाले या समय-समय पर किए जाने वाले कामों के लिए किया जाता है. हालांकि, ये एपीआई काम नहीं कर सकते, क्योंकि सर्विस वर्कर को बंद किए जाने पर शेड्यूलर टाइमर को रद्द कर देगा. इसके बजाय, एक्सटेंशन chrome.alarms API का इस्तेमाल कर सकते हैं.

मेनिफ़ेस्ट में जाकर, "alarms" की अनुमति के लिए अनुरोध करें. इसके अलावा, रिमोट होस्ट की गई जगह से एक्सटेंशन के बारे में सलाह पाने के लिए, आपको होस्ट की अनुमति का अनुरोध करना होगा:

manifest.json:

{
  ...
  "permissions": ["storage", "alarms"],
  "permissions": ["storage"],
  "host_permissions": ["https://extension-tips.glitch.me/*"],
}

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

sw-tips.js:

// Fetch tip & save in storage
const updateTip = async () => {
  const response = await fetch('https://extension-tips.glitch.me/tips.json');
  const tips = await response.json();
  const randomIndex = Math.floor(Math.random() * tips.length);
  return chrome.storage.local.set({ tip: tips[randomIndex] });
};

const ALARM_NAME = 'tip';

// Check if alarm exists to avoid resetting the timer.
// The alarm might be removed when the browser session restarts.
async function createAlarm() {
  const alarm = await chrome.alarms.get(ALARM_NAME);
  if (typeof alarm === 'undefined') {
    chrome.alarms.create(ALARM_NAME, {
      delayInMinutes: 1,
      periodInMinutes: 1440
    });
    updateTip();
  }
}

createAlarm();

// Update tip once a day
chrome.alarms.onAlarm.addListener(updateTip);

सातवां चरण: अन्य कॉन्टेक्स्ट के साथ जानकारी देना

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

शुरुआत में, मेनिफ़ेस्ट में कॉन्टेंट स्क्रिप्ट की जानकारी दें और Chrome API के रेफ़रंस दस्तावेज़ से जुड़ा मैच पैटर्न जोड़ें.

manifest.json:

{
  ...
  "content_scripts": [
    {
      "matches": ["https://developer.chrome.com/docs/extensions/reference/*"],
      "js": ["content.js"]
    }
  ]
}

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

content.js:

(async () => {
  // Sends a message to the service worker and receives a tip in response
  const { tip } = await chrome.runtime.sendMessage({ greeting: 'tip' });

  const nav = document.querySelector('.upper-tabs > nav');
  
  const tipWidget = createDomElement(`
    <button type="button" popovertarget="tip-popover" popovertargetaction="show" style="padding: 0 12px; height: 36px;">
      <span style="display: block; font: var(--devsite-link-font,500 14px/20px var(--devsite-primary-font-family));">Tip</span>
    </button>
  `);

  const popover = createDomElement(
    `<div id='tip-popover' popover style="margin: auto;">${tip}</div>`
  );

  document.body.append(popover);
  nav.append(tipWidget);
})();

function createDomElement(html) {
  const dom = new DOMParser().parseFromString(html, 'text/html');
  return dom.body.firstElementChild;
}

आखिरी चरण में हमारे सर्विस वर्कर के साथ एक मैसेज हैंडलर जोड़ना है, जो कॉन्टेंट स्क्रिप्ट का जवाब रोज़ाना सलाह के साथ भेजता है.

sw-tips.js:

...
// Send tip to content script via messaging
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.greeting === 'tip') {
    chrome.storage.local.get('tip').then(sendResponse);
    return true;
  }
});

जांच करें कि यह काम करता है

पुष्टि करें कि आपके प्रोजेक्ट का फ़ाइल स्ट्रक्चर ऐसा दिखता है:

एक्सटेंशन फ़ोल्डर का कॉन्टेंट: इमेज फ़ोल्डर, Manifest.json, service-worker.js, sw-omnibox.js, sw-tips.js,
और content.js

अपना एक्सटेंशन स्थानीय रूप से लोड करें

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

रेफ़रंस पेज खोलना

  1. ब्राउज़र के पता बार में कीवर्ड "api" डालें.
  2. "Tab" या "space" बटन दबाएं.
  3. एपीआई का पूरा नाम डालें.
    • या पिछली खोजों की सूची में से चुनें
  4. Chrome API के रेफ़रंस पेज से एक नया पेज खुलेगा.

यह कुछ ऐसा दिखना चाहिए:

रनटाइम एपीआई रेफ़रंस खोलने के लिए, क्विक एपीआई रेफ़रंस
Quick API एक्सटेंशन, जो रनटाइम एपीआई को खोल रहा है.

आज का टिप खोलें

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

रोज़ की सलाह इसमें खोलें
Quick API एक्सटेंशन, दिन के सबसे अहम काम की जानकारी दे रहा है.

💡 को हो सकने वाले संभावित सुधार

आज आपने जो कुछ भी सीखा है उसके आधार पर, इनमें से कोई भी काम करने की कोशिश करें:

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

कम्यूनिटी को बढ़ाते रहें!

इस ट्यूटोरियल को पूरा करने पर बधाई 🎉. अन्य शुरुआती ट्यूटोरियल पूरे करके अपने अगले लेवल को और बेहतर बनाएं:

Extension आपको क्या सीखने को मिलेगा
पढ़ने का समय पेजों के किसी खास सेट पर अपने-आप कोई एलिमेंट डालने के लिए.
टैब मैनेजर ब्राउज़र के टैब मैनेज करने वाला पॉप-अप बनाने के लिए.
फ़ोकस मोड एक्सटेंशन कार्रवाई पर क्लिक करने के बाद, मौजूदा पेज पर कोड चलाने के लिए.

और जगहों की सैर करना

एक्सटेंशन सर्विस वर्कर के लर्निंग पाथ को जारी रखने के लिए, हमारा सुझाव है कि आप इन लेखों को एक्सप्लोर करें: