मेनिफेस्ट V3 अब नए क्रोम एक्सटेंशन के लिए एकमात्र विकल्प है, और यह आर्किटेक्चर को सार्थक रूप से बदलता है: पृष्ठभूमि पृष्ठ अल्पकालिक सेवा कार्यकर्ता बन गए हैं, रिमोट कोड निष्पादन पर प्रतिबंध लगा दिया गया है, और नेटवर्क अवरोधन एक घोषणात्मक एपीआई में स्थानांतरित हो गया है। यदि आपने V2 पर विस्तार विकास सीखा है, तो कई आदतें अब काम नहीं करतीं। यह मार्गदर्शिका V3 नियमों के अंतर्गत आरंभ से एक पूर्ण, कार्यशील एक्सटेंशन बनाती है।
📋 Table of Contents
- हम क्या बना रहे हैं
- चरण 1: परियोजना संरचना और घोषणापत्र
- चरण 2: सेवा कार्यकर्ता एक पृष्ठभूमि पृष्ठ नहीं है
- सामग्री स्क्रिप्ट पृष्ठ के DOM में चलती हैं लेकिन एक अलग जावास्क्रिप्ट दुनिया में। वे DOM को पढ़ और संशोधित कर सकते हैं, लेकिन पेज के स्वयं के जावास्क्रिप्ट वेरिएबल्स को नहीं देख सकते हैं। यह अलगाव एक सुरक्षा सुविधा है, न कि काम करने की कोई सीमा।
- पॉपअप एक्सटेंशन एपीआई तक पहुंच वाला एक सामान्य वेब पेज है। हर बार बंद होने पर यह नष्ट हो जाता है, इसलिए इसे स्टेटलेस मानें और खुले में भंडारण से पढ़ें।
- क्षेत्र
- का उपयोग करें , जहां आप स्थिर नियम पंजीकृत करते हैं जिनका मूल्यांकन Chrome स्वयं करता है। आपका एक्सटेंशन कभी भी अनुरोध नहीं देखता है.
- सेवा कर्मी:
- चरण 8: प्रकाशन
- सामान्य गलतियाँ
- नहीं निष्कर्ष
हम क्या बना रहे हैं
एक पेज-एनोटेशन एक्सटेंशन: यह एक टूलबार पॉपअप जोड़ता है, एक कंटेंट स्क्रिप्ट इंजेक्ट करता है जो किसी भी पेज पर चयनित टेक्स्ट को हाइलाइट करता है, प्रति यूआरएल हाइलाइट्स को सेव करता है, और उन्हेंchrome.storageके माध्यम से सिंक करता है। . यह आपके द्वारा वास्तव में उपयोग किए जाने वाले V3 के हर भाग का अभ्यास करता है – पॉपअप यूआई, सामग्री स्क्रिप्ट, सेवा कार्यकर्ता, संदेश, भंडारण और अनुमतियाँ।
चरण 1: परियोजना संरचना और घोषणापत्र
इन फ़ाइलों के साथ एक निर्देशिका बनाएँ। मेनिफेस्ट प्रवेश बिंदु है और क्रोम इसे पहले पढ़ता है।
my-extension/
manifest.json
background.js
content.js
popup.html
popup.js
styles.css
icons/icon16.png icon48.png icon128.png
मेनिफेस्ट संस्करण 3, आपके प्रवेश बिंदु और अनुमतियों की घोषणा करता है। अनुमतियाँ न्यूनतम रखें – प्रत्येक अतिरिक्त अनुमति समीक्षा को धीमा कर देती है और इंस्टॉल के समय उपयोगकर्ताओं को डरा देती है।
{
"manifest_version": 3,
"name": "Page Highlighter",
"version": "1.0.0",
"description": "Highlight and save text on any page.",
"permissions": ["storage", "activeTab", "scripting"],
"host_permissions": ["http://*/*", "https://*/*"],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["content.js"],
"css": ["styles.css"],
"run_at": "document_idle"
}
],
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
}
पसंद करेंactiveTab जब आप कर सकते हैं तो व्यापक होस्ट अनुमतियों से अधिक। उपयोगकर्ता द्वारा आपके एक्सटेंशन आइकन पर क्लिक करने के बाद ही यह वर्तमान टैब तक पहुंच प्रदान करता है, जिसे समीक्षा में उचित ठहराना बहुत आसान है।
चरण 2: सेवा कार्यकर्ता एक पृष्ठभूमि पृष्ठ नहीं है
यह एकल सबसे बड़ा V3 परिवर्तन है. आपकी पृष्ठभूमि स्क्रिप्ट एक सेवा कार्यकर्ता है जिसे क्रोम निष्क्रिय होने पर समाप्त कर देता है और अगले ईवेंट पर पुनरारंभ होता है। आपके द्वारा शीर्ष स्तर पर सेट किया गया कोई भी वेरिएबल समाप्ति के बाद चला जाता है। राज्य कोchrome.storageमें रहना चाहिए , स्मृति में नहीं.
// background.js
// WRONG under V3 — this resets every time the worker restarts.
// let highlightCount = 0;
chrome.runtime.onInstalled.addListener(async () => {
const { highlights } = await chrome.storage.local.get('highlights');
if (!highlights) {
await chrome.storage.local.set({ highlights: {} });
}
});
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'SAVE_HIGHLIGHT') {
saveHighlight(message.payload).then(() => sendResponse({ ok: true }));
// Returning true keeps the message channel open for the async reply.
return true;
}
});
async function saveHighlight({ url, text }) {
const { highlights = {} } = await chrome.storage.local.get('highlights');
const forPage = highlights[url] || [];
forPage.push({ text, createdAt: Date.now() });
highlights[url] = forPage;
await chrome.storage.local.set({ highlights });
}
संदेश में श्रोता को चूकना आसान है और एक क्लासिक बग का कारण बनता है: आपका एसिंक हैंडलर पूरा हो जाता है लेकिन प्रेषक को कभी भी प्रतिक्रिया नहीं मिलती है, क्योंकि श्रोता के अपरिभाषित लौटने पर क्रोम ने चैनल बंद कर दिया है।return trueचरण 3: सामग्री स्क्रिप्ट
सामग्री स्क्रिप्ट पृष्ठ के DOM में चलती हैं लेकिन एक अलग जावास्क्रिप्ट दुनिया में। वे DOM को पढ़ और संशोधित कर सकते हैं, लेकिन पेज के स्वयं के जावास्क्रिप्ट वेरिएबल्स को नहीं देख सकते हैं। यह अलगाव एक सुरक्षा सुविधा है, न कि काम करने की कोई सीमा।
नोट करें
// content.js
document.addEventListener('mouseup', async () => {
const selection = window.getSelection();
const text = selection.toString().trim();
if (text.length < 3) return;
const range = selection.getRangeAt(0);
const mark = document.createElement('mark');
mark.className = 'ext-highlight';
try {
range.surroundContents(mark);
} catch {
// surroundContents throws when the selection crosses element boundaries.
return;
}
await chrome.runtime.sendMessage({
type: 'SAVE_HIGHLIGHT',
payload: { url: location.href, text }
});
selection.removeAllRanges();
});
चारों ओरtry/catch. जब भी चयन कई तत्वों तक फैला होता है तो यह थ्रो हो जाता है, जो वास्तविक पृष्ठों में लगातार होता है। इसे संभालना आपके परीक्षण पृष्ठ पर काम करने वाले एक्सटेंशन और हर जगह काम करने वाले एक्सटेंशन के बीच अंतर है।surroundContentsचरण 4: पॉपअप
पॉपअप एक्सटेंशन एपीआई तक पहुंच वाला एक सामान्य वेब पेज है। हर बार बंद होने पर यह नष्ट हो जाता है, इसलिए इसे स्टेटलेस मानें और खुले में भंडारण से पढ़ें।
इनलाइन स्क्रिप्ट एक्सटेंशन सामग्री सुरक्षा नीति द्वारा अवरुद्ध हैं, इसलिए
<!-- popup.html -->
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body style="width:320px;font:14px system-ui;padding:12px">
<h1 style="font-size:15px;margin:0 0 8px">Highlights on this page</h1>
<ul id="list"></ul>
<script src="popup.js"></script>
</body>
</html>
संदर्भ अनिवार्य है – आप जावास्क्रिप्ट को सीधे HTML में नहीं डाल सकते।<script src> का प्रयोग करें बल्कि
// popup.js
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
const { highlights = {} } = await chrome.storage.local.get('highlights');
const items = highlights[tab.url] || [];
const list = document.getElementById('list');
if (items.length === 0) {
list.innerHTML = '<li>No highlights yet.</li>';
} else {
for (const item of items) {
const li = document.createElement('li');
li.textContent = item.text; // textContent, never innerHTML
list.appendChild(li);
}
}
किसी वेब पेज से उत्पन्न किसी भी मूल्य के लिए। हाइलाइट किया गया टेक्स्ट हमलावर-नियंत्रित डेटा है, और इससे HTML बनाना आपके एक्सटेंशन के विशेषाधिकार प्राप्त संदर्भ में एक सीधा XSS मार्ग है।textContentचरण 5: भंडारण विकल्पinnerHTMLक्रोम आपको तीन भंडारण क्षेत्र देता है और गलत चुनने से मौन विफलताएं होती हैं।
क्षेत्र
कोटा
| के लिए उपयोग करें ~10एमबी (अनुमति के साथ असीमित) | थोक डेटा, कैश्ड सामग्री | ~100KB कुल, 8KB प्रति आइटम |
|---|---|---|
storage.local |
छोटी उपयोगकर्ता सेटिंग्स, सभी डिवाइसों में समन्वयित | ~10एमबी, केवल मेमोरी |
storage.sync |
वह डेटा जो ब्राउज़र पुनरारंभ होने पर नहीं टिकना चाहिए | सामान्य गलती उपयोगकर्ता सामग्री को |
storage.session |
में डालना है क्योंकि सिंक करना वांछनीय लगता है। 8KB प्रति-आइटम सीमा शीघ्रता से पूरी हो जाती है और लिखने के बाद विफल हो जाती है – अक्सर चुपचाप, यदि आप त्रुटियों की जाँच नहीं करते हैं। | चरण 6: नेटवर्क अवरोधन बदला गया |
अवरोधनstorage.sync एपीआई चला गया है. यदि आपको अनुरोधों को ब्लॉक या रीडायरेक्ट करने की आवश्यकता है, तो
का उपयोग करें , जहां आप स्थिर नियम पंजीकृत करते हैं जिनका मूल्यांकन Chrome स्वयं करता है। आपका एक्सटेंशन कभी भी अनुरोध नहीं देखता है.
यह डिज़ाइन द्वारा अधिक प्रतिबंधात्मक है, और यही कारण है कि कई विज्ञापन अवरोधकों को फिर से लिखना पड़ा। यदि आपके एक्सटेंशन का मूल मान रनटाइम पर अनुरोध निकायों के निरीक्षण पर निर्भर करता है, तो V3 वास्तव में इसका समर्थन नहीं कर सकता है।webRequestचरण 7: लोड और डिबगdeclarativeNetRequestखुला
{
"permissions": ["declarativeNetRequest"],
"declarative_net_request": {
"rule_resources": [{
"id": "ruleset_1",
"enabled": true,
"path": "rules.json"
}]
}
}
, डेवलपर मोड सक्षम करें, और “लोड अनपैक्ड” चुनें। तीन अलग-अलग कंसोल मौजूद हैं और यह जानने से कि किसे खोलने से घंटों की बचत होती है:
सेवा कर्मी:
अपने एक्सटेंशन कार्ड पर “सेवा कार्यकर्ता” लिंक पर क्लिक करेंchrome://extensionsपॉपअप:
- पॉपअप पर राइट-क्लिक करें और निरीक्षणचुनें सामग्री स्क्रिप्ट:
- सामान्य पृष्ठ DevTools कंसोल, संदर्भ चयनकर्ता के साथ आपके एक्सटेंशन पर सेटयदि सेवा कर्मी मृत प्रतीत होता है, तो यह अपेक्षित है – यह लगभग 30 सेकंड की निष्क्रियता के बाद समाप्त हो जाता है। किसी ईवेंट को ट्रिगर करें और यह पुनः आरंभ होता है।
- चरण 8: प्रकाशनचरण 8: प्रकाशन
चरण 8: प्रकाशन
चरण 8: प्रकाशन
एक्सटेंशन निर्देशिका सामग्री को ज़िप करें (संलग्न फ़ोल्डर नहीं) और क्रोम वेब स्टोर डेवलपर डैशबोर्ड के माध्यम से अपलोड करें, जिसके लिए एक बार पंजीकरण शुल्क की आवश्यकता होती है। समीक्षा का समय काफी हद तक आपकी अनुमतियों पर निर्भर करता है: केवलactiveTabका उपयोग करने वाला एक्सटेंशन औरstorage आम तौर पर समीक्षा जल्दी से साफ़ हो जाती है, जबकि व्यापक होस्ट अनुमतियाँ प्लसscripting मैन्युअल समीक्षा आकर्षित करें और इसमें काफी अधिक समय लग सकता है। सूची में प्रत्येक अनुमति के लिए स्पष्ट औचित्य लिखें – समीक्षक अस्पष्ट स्पष्टीकरणों को अस्वीकार करते हैं।
सामान्य गलतियाँ
सेवा कार्यकर्ता ग्लोबल्स में राज्य का भंडारण। समाप्ति पर यह लुप्त हो जाता है।chrome.storage.
का प्रयोग करें भूल जानाreturn true async संदेश श्रोताओं में। प्रतिक्रिया कभी नहीं आती और असफलता खामोश रहती है।
निवेदन<all_urls> कबactiveTab करूँगा. यह समीक्षा को धीमा कर देता है और इंस्टॉल को कम कर देता है।
रिमोट कोड लोड हो रहा है. V3 इसे पूरी तरह से प्रतिबंधित करता है। सभी निष्पादन योग्य कोड को पैकेज में शिप किया जाना चाहिए, जिसका अर्थ है कोई सीडीएन स्क्रिप्ट नहीं और कोईeval.
नहीं निष्कर्ष
प्रकट V3 विकास कुछ विषयों तक सीमित है:सेवा कर्मी को राज्यविहीन मानें और सभी राज्य कोchrome.storageमें रखें , काम करने वाली सबसे संकीर्ण अनुमतियों का अनुरोध करें,textContentका उपयोग करें किसी पृष्ठ से प्राप्त किसी भी चीज़ के लिए, याद रखेंreturn true एसिंक संदेश हैंडलर के लिए, और पैकेज के अंदर कोड की प्रत्येक पंक्ति को शिप करें. शुरू से ही उन बाधाओं के साथ निर्माण करें और प्लेटफ़ॉर्म आपके रास्ते से दूर रहता है – उन्हें V2-आकार के डिज़ाइन पर फिर से फिट करना वह जगह है जहाँ दर्द रहता है।
🔗 Share this article
✍️ Leave a Comment