Tutorial che illustra i concetti relativi ai service worker delle estensioni
Panoramica
Questo tutorial fornisce un'introduzione ai service worker delle estensioni di Chrome. Nell'ambito di questo tutorial, creerai un'estensione che consente agli utenti di navigare rapidamente alle pagine di riferimento dell'API Chrome utilizzando la omnibox. Imparerai come:
- Registrare il service worker e importare i moduli.
- Eseguire il debug del service worker dell'estensione.
- Gestire lo stato e gestire gli eventi.
- Attivare eventi periodici.
- Comunicare con gli script di contenuti.
Prima di iniziare
Questa guida presuppone che tu abbia una conoscenza di base dello sviluppo web. Ti consigliamo di consultare Estensioni 101 e Hello World per un'introduzione allo sviluppo di estensioni.
Creare l'estensione
Inizia creando una nuova directory chiamata quick-api-reference per contenere i file dell'estensione o
scarica il codice sorgente dal nostro repository di esempi GitHub.
Passaggio 1: registra il service worker
Crea il file manifest nella directory principale del progetto e aggiungi il seguente codice:
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"
}
}
Le estensioni registrano il service worker nel manifest, che accetta un solo file JavaScript.
Non è necessario chiamare navigator.serviceWorker.register(), come faresti in una pagina web.
Crea una cartella images e scarica le icone al suo interno.
Consulta i primi passaggi del tutorial Tempo di lettura per scoprire di più sui metadati e sulle icone dell'estensione nel manifest.
Passaggio 2: importa più moduli del service worker
Il nostro service worker implementa due funzionalità. Per una migliore manutenibilità, implementeremo ogni funzionalità in un modulo separato. Innanzitutto, dobbiamo dichiarare il service worker come modulo ES nel nostro manifest, il che ci consente di importare i moduli nel service worker:
manifest.json:
{
"background": {
"service_worker": "service-worker.js",
"type": "module"
},
}
Crea il file service-worker.js e importa due moduli:
import './sw-omnibox.js';
import './sw-tips.js';
Crea questi file e aggiungi un log della console a ciascuno.
sw-omnibox.js:
console.log("sw-omnibox.js");
sw-tips.js:
console.log("sw-tips.js");
Consulta Importare script per scoprire altri modi per importare più file in un service worker.
(Facoltativo) Eseguire il debug del service worker
Ti spiegherò come trovare i log del service worker e sapere quando è terminato. Innanzitutto, segui le istruzioni per caricare un'estensione non pacchettizzata.
Dopo 30 secondi vedrai "service worker (inactive)", il che significa che il service worker è terminato. Fai clic sul link "service worker (inactive)" per esaminarlo. L'animazione seguente mostra questo passaggio.
Hai notato che l'ispezione del service worker lo ha riattivato? L'apertura del service worker negli strumenti per sviluppatori lo manterrà attivo. Per assicurarti che l'estensione si comporti correttamente quando il service worker viene terminato, ricordati di chiudere gli strumenti per sviluppatori.
Ora, interrompi l'estensione per scoprire dove trovare gli errori. Un modo per farlo è eliminare ".js" dall'importazione './sw-omnibox.js' nel file service-worker.js. Chrome non sarà in grado di registrare il service worker.
Torna a chrome://extensions e aggiorna l'estensione. Verranno visualizzati due errori:
Service worker registration failed. Status code: 3.
An unknown error occurred when fetching the script.
Consulta Eseguire il debug delle estensioni per scoprire altri modi per eseguire il debug del service worker dell'estensione.
Passaggio 4: inizializza lo stato
Chrome arresterà i service worker se non sono necessari. Utilizziamo l'API chrome.storage per mantenere lo stato tra le sessioni del service worker. Per l'accesso allo spazio di archiviazione, dobbiamo richiedere l'autorizzazione nel manifest:
manifest.json:
{
...
"permissions": ["storage"],
}
Innanzitutto, salva i suggerimenti predefiniti nello spazio di archiviazione. Possiamo inizializzare lo stato quando l'estensione viene installata per la prima volta ascoltando l'evento 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']
});
}
});
I service worker non hanno accesso diretto all'oggetto window e pertanto non possono utilizzare window.localStorage per archiviare i valori. Inoltre, i service worker sono ambienti di esecuzione di breve durata; vengono terminati ripetutamente durante la sessione del browser di un utente, il che li rende incompatibili con le variabili globali. Utilizza invece chrome.storage.local, che archivia i dati sulla macchina locale.
Consulta Mantenere i dati anziché utilizzare le variabili globali per scoprire altre opzioni di archiviazione per i service worker delle estensioni.
Passaggio 5: registra gli eventi
Tutti i listener di eventi devono essere registrati staticamente nell'ambito globale del service worker. In altre parole, i listener di eventi non devono essere nidificati nelle funzioni asincrone. In questo modo, Chrome può garantire che tutti i gestori di eventi vengano ripristinati in caso di riavvio del service worker.
In questo esempio, utilizzeremo l'API chrome.omnibox, ma prima dobbiamo dichiarare il trigger della parola chiave della omnibox nel manifest:
manifest.json:
{
...
"minimum_chrome_version": "102",
"omnibox": {
"keyword": "api"
},
}
Ora, registra i listener di eventi della omnibox al livello superiore dello script. Quando l'utente inserisce la parola chiave della omnibox (api) nella barra degli indirizzi seguita da un tab o uno spazio, Chrome visualizzerà un elenco di suggerimenti in base alle parole chiave nello spazio di archiviazione. L'evento onInputChanged(), che accetta l'input corrente dell'utente e un oggetto suggestResult, è responsabile della compilazione di questi suggerimenti.
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);
});
Dopo che l'utente ha selezionato un suggerimento, onInputEntered() aprirà la pagina di riferimento dell'API Chrome corrispondente.
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);
});
La funzione updateHistory() accetta l'input della omnibox e lo salva in storage.local. In questo modo, il termine di ricerca più recente può essere utilizzato in un secondo momento come suggerimento della omnibox.
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 });
}
Passaggio 6: configura un evento ricorrente
I metodi setTimeout() o setInterval() sono di uso comune per eseguire attività ritardate o periodiche. Tuttavia, queste API possono non riuscire perché lo scheduler annullerà i timer quando il service worker viene terminato. Le estensioni possono invece utilizzare l'API chrome.alarms.
Inizia richiedendo l'autorizzazione "alarms" nel manifest:
manifest.json:
{
...
"permissions": ["storage"],
"permissions": ["storage", "alarms"],
}
L'estensione recupererà tutti i suggerimenti, ne sceglierà uno a caso e lo salverà nello spazio di archiviazione. Creeremo una sveglia che verrà attivata una volta al giorno per aggiornare il suggerimento. Gli allarmi non vengono salvati quando chiudi Chrome. Pertanto, dobbiamo verificare se l'allarme esiste e crearlo in caso contrario.
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);
Passaggio 7: comunica con altri contesti
Le estensioni utilizzano gli script di contenuti per leggere e modificare i contenuti della pagina. Quando un utente visita una pagina di riferimento dell'API Chrome, lo script di contenuti dell'estensione aggiornerà la pagina con il suggerimento del giorno. Invia un messaggio per richiedere il suggerimento del giorno al service worker.
Inizia dichiarando lo script di contenuti nel manifest e aggiungendo il pattern di corrispondenza corrispondente alla documentazione di riferimento dell'API Chrome.
manifest.json:
{
...
"content_scripts": [
{
"matches": ["https://developer.chrome.com/docs/extensions/reference/*"],
"js": ["content.js"]
}
]
}
Crea un nuovo file di contenuti. Il seguente codice invia un messaggio al service worker che richiede il suggerimento. Poi, aggiunge un pulsante che aprirà un popover contenente il suggerimento dell'estensione. Questo codice utilizza la nuova API Popover della piattaforma web.
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;
}
Il passaggio finale consiste nell'aggiungere un gestore di messaggi al nostro service worker che invia una risposta allo script di contenuti con il suggerimento giornaliero.
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;
}
});
Verificare che funzioni
Verifica che la struttura dei file del progetto sia simile alla seguente:

Caricare l'estensione localmente
Per caricare un'estensione non pacchettizzata in modalità sviluppatore, segui i passaggi descritti in Hello world.
Aprire una pagina di riferimento
- Inserisci la parola chiave "api" nella barra degli indirizzi del browser.
- Premi "Tab" o "Spazio".
- Inserisci il nome completo dell'API.
- OPPURE scegli da un elenco di ricerche precedenti
- Si aprirà una nuova pagina con la pagina di riferimento dell'API Chrome.
Dovrebbe avere il seguente aspetto:
Aprire il suggerimento del giorno
Fai clic sul pulsante Suggerimento nella barra di navigazione per aprire il suggerimento dell'estensione.
🎯 Potenziali miglioramenti
In base a ciò che hai imparato oggi, prova a eseguire una delle seguenti operazioni:
- Esplora un altro modo per implementare i suggerimenti della omnibox.
- Crea la tua finestra modale personalizzata per visualizzare il suggerimento dell'estensione.
- Apri una pagina aggiuntiva alle pagine API di riferimento delle estensioni web di MDN.
Continua a creare!
Congratulazioni per aver completato questo tutorial 🎉. Continua a migliorare le tue competenze completando altri tutorial per principianti:
| Estensione | Cosa imparerai a fare |
|---|---|
| Tempo di lettura | Per inserire automaticamente un elemento in un insieme specifico di pagine. |
| Gestore schede | Per creare un popup che gestisce le schede del browser. |
| Modalità Niente distrazioni | Per eseguire il codice nella pagina corrente dopo aver fatto clic sull'azione dell'estensione. |
Continua a esplorare
Per continuare il tuo percorso di apprendimento dei service worker delle estensioni, ti consigliamo di esplorare i seguenti articoli: