Tutorial yang membahas konsep service worker ekstensi
Ringkasan
Tutorial ini memberikan pengantar tentang pekerja layanan Ekstensi Chrome. Sebagai bagian dari tutorial ini, Anda akan membuat ekstensi yang memungkinkan pengguna membuka halaman referensi API Chrome dengan cepat menggunakan omnibox. Anda akan mempelajari cara:
- Daftarkan pekerja layanan dan impor modul.
- Lakukan debug pada pekerja layanan ekstensi Anda.
- Mengelola status dan menangani peristiwa.
- Memicu peristiwa berkala.
- Berkomunikasi dengan skrip konten.
Sebelum memulai
Panduan ini mengasumsikan bahwa Anda memiliki pengalaman pengembangan web dasar. Sebaiknya tinjau Ekstensi 101 dan Hello World untuk pengantar pengembangan ekstensi.
Mem-build ekstensi
Mulailah dengan membuat direktori baru bernama quick-api-reference
untuk menyimpan file ekstensi, atau download kode sumber dari repositori contoh GitHub kami.
Langkah 1: Daftarkan pekerja layanan
Buat file manifest di root project dan tambahkan kode berikut:
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"
}
}
Ekstensi mendaftarkan service worker-nya dalam manifes, yang hanya memerlukan satu file JavaScript.
Anda tidak perlu memanggil navigator.serviceWorker.register()
, seperti yang Anda lakukan di halaman web.
Buat folder images
, lalu download ikon ke dalamnya.
Lihat langkah pertama tutorial Waktu membaca untuk mempelajari lebih lanjut metadata dan ikon ekstensi dalam manifes.
Langkah 2: Impor beberapa modul service worker
Pekerja layanan kami menerapkan dua fitur. Untuk pemeliharaan yang lebih baik, kita akan menerapkan setiap fitur dalam modul terpisah. Pertama, kita perlu mendeklarasikan pekerja layanan sebagai Modul ES dalam manifes, yang memungkinkan kita mengimpor modul di pekerja layanan:
manifest.json:
{
"background": {
"service_worker": "service-worker.js",
"type": "module"
},
}
Buat file service-worker.js
dan impor dua modul:
import './sw-omnibox.js';
import './sw-tips.js';
Buat file ini dan tambahkan log konsol ke setiap file.
sw-omnibox.js:
console.log("sw-omnibox.js");
sw-tips.js:
console.log("sw-tips.js");
Lihat Mengimpor skrip untuk mempelajari cara lain mengimpor beberapa file di pekerja layanan.
Opsional: Men-debug pekerja layanan
Saya akan menjelaskan cara menemukan log pekerja layanan dan mengetahui kapan log tersebut dihentikan. Pertama, ikuti petunjuk untuk Memuat ekstensi yang diekstrak.
Setelah 30 detik, Anda akan melihat "service worker (inactive)" yang berarti pekerja layanan telah dihentikan. Klik link "service worker (tidak aktif)" untuk memeriksanya. Animasi berikut menunjukkan hal ini.
Apakah Anda melihat bahwa memeriksa pekerja layanan membangunkannya? Membuka pekerja layanan di devtools akan membuatnya tetap aktif. Untuk memastikan ekstensi berperilaku dengan benar saat pekerja layanan dihentikan, jangan lupa untuk menutup DevTools.
Sekarang, pecahkan ekstensi untuk mempelajari tempat menemukan error. Salah satu cara melakukannya adalah dengan menghapus ".js" dari impor './sw-omnibox.js'
dalam file service-worker.js
. Chrome tidak akan dapat mendaftarkan pekerja layanan.
Kembali ke chrome://extensions dan muat ulang ekstensi. Anda akan melihat dua error:
Service worker registration failed. Status code: 3.
An unknown error occurred when fetching the script.
Lihat Melakukan debug ekstensi untuk mengetahui cara lainnya men-debug pekerja layanan ekstensi.
Langkah 4: Melakukan inisialisasi status
Chrome akan menonaktifkan pekerja layanan jika tidak diperlukan. Kita menggunakan chrome.storage
API untuk mempertahankan status di seluruh sesi pekerja layanan. Untuk akses penyimpanan, kita perlu meminta izin dalam manifes:
manifest.json:
{
...
"permissions": ["storage"],
}
Pertama, simpan saran default ke penyimpanan. Kita dapat menginisialisasi status saat ekstensi pertama kali diinstal dengan memproses peristiwa 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']
});
}
});
Pekerja layanan tidak memiliki akses langsung ke objek jendela sehingga tidak dapat menggunakan
window.localStorage
untuk menyimpan nilai. Selain itu, pekerja layanan adalah lingkungan eksekusi berumur pendek;
mereka dihentikan berulang kali selama sesi browser pengguna, yang membuatnya tidak kompatibel dengan
variabel global. Sebagai gantinya, gunakan chrome.storage.local
yang menyimpan data di komputer lokal.
Lihat Mempertahankan data, bukan menggunakan variabel global, guna mempelajari opsi penyimpanan lainnya untuk pekerja layanan ekstensi.
Langkah 5: Daftarkan peristiwa Anda
Semua pemroses peristiwa harus didaftarkan secara statis dalam cakupan global pekerja layanan. Dengan kata lain, pemroses peristiwa tidak boleh disusun bertingkat dalam fungsi asinkron. Dengan cara ini, Chrome dapat memastikan bahwa semua pengendali peristiwa dipulihkan jika pekerja layanan dimulai ulang.
Dalam contoh ini, kita akan menggunakan chrome.omnibox
API, tetapi pertama-tama kita harus mendeklarasikan pemicu kata kunci omnibox dalam manifes:
manifest.json:
{
...
"minimum_chrome_version": "102",
"omnibox": {
"keyword": "api"
},
}
Sekarang, daftarkan pemroses peristiwa omnibox di tingkat atas skrip. Saat pengguna memasukkan kata kunci omnibox (api
) di kolom URL, diikuti tab atau spasi, Chrome akan menampilkan daftar saran berdasarkan kata kunci di penyimpanan. Peristiwa onInputChanged()
, yang menggunakan input pengguna saat ini dan objek suggestResult
, bertanggung jawab untuk mengisi saran ini.
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);
});
Setelah pengguna memilih saran, onInputEntered()
akan membuka halaman referensi Chrome API yang sesuai.
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);
});
Fungsi updateHistory()
mengambil input omnibox dan menyimpannya ke storage.local
. Dengan demikian, istilah penelusuran terbaru dapat digunakan nanti sebagai saran 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 });
}
Langkah 6: Menyiapkan peristiwa berulang
Metode setTimeout()
atau setInterval()
biasanya digunakan untuk melakukan tugas yang tertunda atau berkala. Namun, API ini dapat gagal karena penjadwal akan membatalkan timer saat pekerja
layanan dihentikan. Sebagai gantinya, ekstensi dapat menggunakan chrome.alarms
API.
Mulai dengan meminta izin "alarms"
dalam manifes. Selain itu, untuk mengambil tips ekstensi dari lokasi yang dihosting jarak jauh, Anda perlu meminta izin host:
manifest.json:
{
...
"permissions": ["storage"],
"permissions": ["storage", "alarms"],
"host_permissions": ["https://extension-tips.glitch.me/*"],
}
Ekstensi akan mengambil semua tips, memilih satu secara acak, dan menyimpannya ke penyimpanan. Kami akan membuat alarm yang akan dipicu sekali sehari untuk memperbarui tip. Alarm tidak disimpan saat Anda menutup Chrome. Jadi, kita perlu memeriksa apakah alarm ada dan membuatnya jika tidak ada.
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);
Langkah 7: Berkomunikasi dengan konteks lain
Ekstensi menggunakan skrip konten untuk membaca dan mengubah konten halaman. Saat pengguna mengunjungi halaman referensi Chrome API, skrip konten ekstensi akan memperbarui halaman dengan tips hari itu. Fungsi ini mengirim pesan untuk meminta tips hari ini dari pekerja layanan.
Mulai dengan mendeklarasikan skrip konten dalam manifes dan tambahkan pola pencocokan yang sesuai dengan dokumentasi referensi Chrome API.
manifest.json:
{
...
"content_scripts": [
{
"matches": ["https://developer.chrome.com/docs/extensions/reference/*"],
"js": ["content.js"]
}
]
}
Buat file konten baru. Kode berikut mengirim pesan ke pekerja layanan yang meminta tip. Kemudian, tambahkan tombol yang akan membuka pop-up yang berisi tips ekstensi. Kode ini menggunakan Popover API platform web baru.
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;
}
Langkah terakhir adalah menambahkan pengendali pesan ke pekerja layanan yang akan mengirimkan balasan ke skrip konten berisi tip harian.
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;
}
});
Menguji apakah berfungsi
Pastikan struktur file project Anda terlihat seperti berikut:
Memuat ekstensi secara lokal
Untuk memuat ekstensi yang diekstrak dalam mode developer, ikuti langkah-langkah di Hello world.
Membuka halaman referensi
- Masukkan kata kunci "api" di kolom URL browser.
- Tekan "tab" atau "spasi".
- Masukkan nama lengkap API.
- ATAU pilih dari daftar penelusuran sebelumnya
- Halaman baru akan terbuka ke halaman referensi Chrome API.
Kodenya akan terlihat seperti berikut:
Buka tips hari ini
Klik tombol Tips yang terletak di menu navigasi untuk membuka tips ekstensi.
🎯 Potensi peningkatan
Berdasarkan hal yang telah Anda pelajari hari ini, coba selesaikan salah satu hal berikut:
- Pelajari cara lain untuk menerapkan saran omnibox.
- Buat modal kustom Anda sendiri untuk menampilkan tips ekstensi.
- Buka halaman tambahan ke halaman API referensi Ekstensi Web MDN.
Teruslah membangun!
Selamat, Anda telah menyelesaikan tutorial ini 🎉. Tingkatkan keterampilan Anda dengan menyelesaikan tutorial pemula lainnya:
Perluasan | Yang akan Anda pelajari |
---|---|
Waktu membaca | Untuk menyisipkan elemen di kumpulan halaman tertentu secara otomatis. |
Pengelola Tab | Untuk membuat pop-up yang mengelola tab browser. |
Mode Fokus | Untuk menjalankan kode di halaman saat ini setelah mengklik tindakan ekstensi. |
Jelajahi lebih jauh
Untuk melanjutkan jalur pembelajaran pekerja layanan ekstensi, sebaiknya baca artikel berikut: