הדרכה שכוללת מושגים בנושא extension service worker
סקירה כללית
המדריך הזה מספק מבוא ל-service workers של תוספי Chrome. במסגרת המדריך הזה, תיצרו תוסף שיאפשר למשתמשים לנווט במהירות לדפי העיון ב-Chrome API באמצעות תיבת הכתובות. תלמדו איך:
- רושמים את קובץ השירות (service worker) ומייבאים מודולים.
- ניפוי באגים ב-service worker של התוסף.
- ניהול מצב וטיפול באירועים.
- הפעלת אירועים תקופתיים.
- תקשורת עם סקריפטים של תוכן.
לפני שמתחילים
במדריך הזה אנחנו יוצאים מנקודת הנחה שיש לכם ניסיון בסיסי בפיתוח אתרים. מומלץ לעיין במאמרים Extensions 101 ו-Hello World כדי לקבל מבוא לפיתוח תוספים.
פיתוח התוסף
מתחילים ביצירת ספרייה חדשה בשם quick-api-reference
כדי לאחסן את קובצי התוסף, או מורידים את קוד המקור ממאגר הדוגמאות ב-GitHub.
שלב 1: רישום של Service Worker
יוצרים את קובץ manifest בבסיס הפרויקט ומוסיפים את הקוד הבא:
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"
}
}
תוספים רושמים את ה-service worker שלהם במניפסט, שכולל רק קובץ JavaScript אחד.
אין צורך להתקשר אל navigator.serviceWorker.register()
, כמו שמתקשרים בדף אינטרנט.
יוצרים תיקייה בשם images
ואז מורידים את הסמלים לתיקייה.
במאמר בנושא זמן קריאה מוסבר על המטא-נתונים ועל הסמלים של התוסף במניפסט.
שלב 2: מייבאים כמה מודולים של Service Worker
ה-service worker שלנו מטמיע שתי תכונות. כדי לשפר את יכולת התחזוקה, נטמיע כל תכונה במודול נפרד. קודם כל, צריך להגדיר את ה-service worker כ-ES Module במניפסט, כדי שנוכל לייבא מודולים ל-service worker:
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");
במאמר ייבוא סקריפטים מוסבר על דרכים נוספות לייבוא של כמה קבצים ב-Service Worker.
אופציונלי: ניפוי באגים ב-service worker
אני אסביר לך איך למצוא את היומנים של Service Worker ואיך לדעת מתי הוא הסתיים. קודם כול, פועלים לפי ההוראות לטעינת תוסף לא ארוז.
אחרי 30 שניות יופיע הכיתוב service worker (inactive) (סוכן שירות (לא פעיל)), כלומר סוכן השירות הסתיים. כדי לבדוק את ה-service worker, לוחצים על הקישור service worker (inactive) (סרוויס וורקר (לא פעיל)). אפשר לראות את זה באנימציה הבאה.
שמת לב שכשבודקים את קובץ השירות (service worker), הוא מתעורר? פתיחת ה-service worker בכלי הפיתוח תשמור אותו פעיל. כדי לוודא שהתוסף מתנהג בצורה תקינה כשמפסיקים את פעולת ה-Service Worker, חשוב לזכור לסגור את כלי הפיתוח.
עכשיו נשבור את התוסף כדי ללמוד איפה נמצאות השגיאות. אחת הדרכים לעשות זאת היא למחוק את .js מההצהרה './sw-omnibox.js'
import בקובץ service-worker.js
. ל-Chrome לא תהיה אפשרות לרשום את קובץ השירות (service worker).
חוזרים אל chrome://extensions ומרעננים את התוסף. יוצגו שתי שגיאות:
Service worker registration failed. Status code: 3.
An unknown error occurred when fetching the script.
במאמר ניפוי באגים בתוספים מוסברות דרכים נוספות לניפוי באגים ב-service worker של התוסף.
שלב 4: מאתחלים את המצב
אם אין צורך ב-Service Workers, Chrome ישבית אותם. אנחנו משתמשים ב-API chrome.storage
כדי לשמור את המצב בין סשנים של Service Worker. כדי לקבל גישה לאחסון, צריך לבקש הרשאה במניפסט:
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']
});
}
});
ל-Service Workers אין גישה ישירה לאובייקט החלון, ולכן הם לא יכולים להשתמש ב-window.localStorage
כדי לאחסן ערכים. בנוסף, service workers הם סביבות הרצה לטווח קצר. הם מסיימים את הפעולה שלהם שוב ושוב במהלך סשן הדפדפן של המשתמש, ולכן הם לא תואמים למשתנים גלובליים. במקום זאת, צריך להשתמש ב-chrome.storage.local
ששומר נתונים במכונה המקומית.
במאמר שמירת נתונים במקום שימוש במשתנים גלובליים מוסבר על אפשרויות אחסון אחרות ל-service workers של תוספים.
שלב 5: רושמים את האירועים
צריך לרשום את כל מאזיני האירועים באופן סטטי בהיקף הגלובלי של ה-service worker. במילים אחרות, אסור להטמיע event listeners בפונקציות אסינכרוניות. כך Chrome יכול לוודא שכל המטפלים באירועים ישוחזרו במקרה של אתחול מחדש של Service Worker.
בדוגמה הזו נשתמש ב-API chrome.omnibox
, אבל קודם צריך להצהיר על מילת המפתח להפעלת סרגל הכתובות במניפסט:
manifest.json:
{
...
"minimum_chrome_version": "102",
"omnibox": {
"keyword": "api"
},
}
עכשיו, רושמים את פונקציות event listener של תיבת הכתובת ברמה העליונה של הסקריפט. כשהמשתמש מזין את מילת המפתח של סרגל הכתובות (api
) בסרגל הכתובות ואחריה מקש Tab או רווח, 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);
});
אחרי שהמשתמש בוחר הצעה, onInputEntered()
יפתח את דף ההפניה המתאים ל-Chrome API.
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 });
}
שלב 6: הגדרת אירוע חוזר
בדרך כלל משתמשים בשיטות setTimeout()
או setInterval()
כדי לבצע משימות מושהות או תקופתיות. עם זאת, יכול להיות שה-API האלה ייכשלו כי המתזמן יבטל את הטיימרים כשה-service worker יופסק. במקום זאת, תוספים יכולים להשתמש ב-API chrome.alarms
.
כדי להתחיל, צריך לבקש את ההרשאה "alarms"
במניפסט:
manifest.json:
{
...
"permissions": ["storage"],
"permissions": ["storage", "alarms"],
}
התוסף יאחזר את כל הטיפים, יבחר אחד באופן אקראי וישמור אותו באחסון. אנחנו ניצור התראה שתופעל פעם ביום כדי לעדכן את הטיפ. השעונים המעוררים לא נשמרים כשסוגרים את Chrome. לכן אנחנו צריכים לבדוק אם האזעקה קיימת, ואם לא, ליצור אותה.
sw-tips.js:
// Fetch tip & save in storage
const updateTip = async () => {
const response = await fetch('https://chrome.dev/f/extension_tips/');
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);
שלב 7: תקשורת עם הקשרים האחרים
תוספים משתמשים בסקריפטים של תוכן כדי לקרוא ולשנות את התוכן של הדף. כשמשתמש נכנס לדף הפניה ל-Chrome API, סקריפט התוכן של התוסף מעדכן את הדף עם טיפ היום. הוא שולח הודעה כדי לבקש את הטיפ היומי מ-Service Worker.
מתחילים בהצהרה על סקריפט התוכן במניפסט ומוסיפים את תבנית ההתאמה שמתאימה למסמכי העיון של Chrome API.
manifest.json:
{
...
"content_scripts": [
{
"matches": ["https://developer.chrome.com/docs/extensions/reference/*"],
"js": ["content.js"]
}
]
}
יוצרים קובץ תוכן חדש. הקוד הבא שולח הודעה אל Service Worker ומבקש את הטיפ. לאחר מכן, מוסיף כפתור שבלחיצה עליו ייפתח חלון קופץ עם הטיפ לגבי התוסף. הקוד הזה משתמש ב-Popover API, ממשק API חדש לפלטפורמות אינטרנט.
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;
}
השלב האחרון הוא להוסיף ל-service worker שלנו פונקציית handler של הודעות, שתשלח תשובה לסקריפט התוכן עם הטיפ היומי.
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;
}
});
בודקים שהכול עובד
מוודאים שמבנה הקבצים של הפרויקט נראה כך:
טעינת התוסף באופן מקומי
כדי לטעון תוסף לא ארוז במצב פיתוח, פועלים לפי השלבים במאמר Hello world.
פתיחת דף עזר
- מזינים את מילת המפתח api בסרגל הכתובות של הדפדפן.
- מקישים על Tab או על מקש הרווח.
- מזינים את השם המלא של ה-API.
- או בוחרים מתוך רשימה של חיפושים קודמים
- ייפתח דף חדש עם הפניה ל-Chrome API.
הוא אמור להיראות כך:

פתיחת העצה היומית
לוחצים על לחצן הטיפ בסרגל הניווט כדי לפתוח את הטיפ של התוסף.

🎯 שיפורים אפשריים
על סמך מה שלמדת היום, נסה לבצע אחת מהפעולות הבאות:
- אפשר לנסות דרך אחרת להטמיע את ההצעות בתיבת הכתובת.
- ליצור חלון קופץ מותאם אישית משלכם להצגת הטיפ לגבי התוסף.
- פותחים דף נוסף לדפי ה-API של Web Extensions ב-MDN.
ממשיכים לבנות!
סיימת את המדריך הזה 🎉. כדי להמשיך לשפר את הכישורים שלך, כדאי לעבור על מדריכים נוספים למתחילים:
Extension | מה תלמדו |
---|---|
זמן קריאה | כדי להוסיף רכיב לקבוצה מסוימת של דפים באופן אוטומטי. |
Tabs Manager | כדי ליצור חלון קופץ שמנהל כרטיסיות בדפדפן. |
מצב פוקוס | כדי להריץ קוד בדף הנוכחי אחרי לחיצה על פעולת התוסף. |
מידע נוסף על היעדים
כדי להמשיך את תוכנית הלימודים בנושא Service Worker של תוספים, מומלץ לעיין במאמרים הבאים: