Hizmet işçileriyle etkinlikleri işleme

Uzantı hizmet çalışanı kavramlarını kapsayan eğitim

Genel Bakış

Bu eğitimde, Chrome uzantısı hizmet işçileri hakkında bilgi verilmektedir. Bu eğitim kapsamında, kullanıcıların her şey bir arada kutuyu kullanarak Chrome API referans sayfalarına hızlıca gitmelerine olanak tanıyan bir uzantı oluşturacaksınız. Aşağıdakileri nasıl yapacağınızı öğreneceksiniz:

  • Hizmet çalışanınızı kaydedin ve modülleri içe aktarın.
  • Uzantı hizmet işçinizde hata ayıklama.
  • Durumu yönetme ve etkinlikleri işleme
  • Düzenli etkinlikleri tetikleyin.
  • İçerik komut dosyalarıyla iletişime geçebilir.

Başlamadan önce

Bu kılavuzda, temel düzeyde web geliştirme deneyiminiz olduğu varsayılmaktadır. Uzantı geliştirmeyle ilgili giriş bilgileri için Uzantılar 101 ve Merhaba Dünya başlıklı makaleleri incelemenizi öneririz.

Uzantıyı derleme

Uzatma dosyalarını barındıracak quick-api-reference adlı yeni bir dizin oluşturarak başlayın veya GitHub örnekleri deponuzda kaynak kodu indirin.

1. adım: Hizmet çalışanını kaydedin

Projenin kökünde manifest dosyasını oluşturun ve aşağıdaki kodu ekleyin:

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"
  }
}

Uzantılar, hizmet işçilerini manifest dosyasına kaydeder. Bu işlem için yalnızca tek bir JavaScript dosyası gerekir. Web sayfasında yaptığınız gibi navigator.serviceWorker.register()'yi çağırmanız gerekmez.

images klasörü oluşturun ve simgeleri bu klasöre indirin.

Uzantıdaki metadata ve manifestteki simgeler hakkında daha fazla bilgi edinmek için Okuma Zamanı eğitimindeki ilk adımlara göz atın.

2. Adım: Birden fazla hizmet çalışanı modülü içe aktarın

Hizmet işleyicimiz iki özellik uygular. Daha iyi sürdürülebilirlik için her özelliği ayrı bir modüle uygulayacağız. Öncelikle, hizmet çalışanını manifest'imizde ES modülü olarak tanımlamamız gerekir. Bu, hizmet çalışanımıza modül içe aktarmamıza olanak tanır:

manifest.json:

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

service-worker.js dosyasını oluşturun ve iki modülü içe aktarın:

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

Bu dosyaları oluşturun ve her birine bir konsol günlüğü ekleyin.

sw-omnibox.js:

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

sw-tips.js:

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

Bir hizmet çalışanına birden fazla dosya aktarmanın diğer yolları hakkında bilgi edinmek için Komut dosyalarını içe aktarma başlıklı makaleyi inceleyin.

İsteğe bağlı: Hizmet çalışanında hata ayıklama

Hizmet çalışanı günlüklerini nasıl bulacağınızı ve ne zaman sonlandırıldığını nasıl anlayacağınızı açıklayacağım. Öncelikle, Ayıklanmış bir uzantıyı yükleme talimatlarını uygulayın.

30 saniye sonra "hizmet çalışanı (etkin değil)" ifadesini görürsünüz. Bu, hizmet çalışanının sonlandırıldığı anlamına gelir. İncelemek için "hizmet çalışanı (etkin değil)" bağlantısını tıklayın. Aşağıdaki animasyonda bu durum gösterilmektedir.

Hizmet çalışanını incelediğinizde uyandığına dikkat ettiniz mi? Hizmet çalışanını devtools'de açmak, çalışanı etkin durumda tutar. Hizmet çalışanınız sonlandırıldığında uzantınızın doğru şekilde davrandığından emin olmak için DevTools'u kapatmayı unutmayın.

Ardından, hataların nerede bulunacağını öğrenmek için uzantıyı kesin. Bunu yapmanın bir yolu, service-worker.js dosyasındaki './sw-omnibox.js' içe aktarma işleminden ".js" uzantısını silmektir. Chrome, hizmet çalışanını kaydedemez.

chrome://extensions adresine geri dönüp uzantıyı yenileyin. İki hata görürsünüz:

Service worker registration failed. Status code: 3.

An unknown error occurred when fetching the script.

Uzantı hizmet işçisinde hata ayıklamayla ilgili daha fazla yöntem için Uzantılarda hata ayıklama başlıklı makaleyi inceleyin.

4. Adım: Durumu başlatın

Chrome, gerekli olmayan hizmet işçilerini kapatır. Hizmet çalışanı oturumlarında durumu korumak için chrome.storage API'sini kullanırız. Depolama alanına erişim için manifest dosyasında izin istememiz gerekir:

manifest.json:

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

Öncelikle varsayılan önerileri depolama alanına kaydedin. runtime.onInstalled() etkinliğini dinleyerek uzantı ilk kez yüklendiğinde durumu başlatabiliriz:

sw-omnibox.js:

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

Hizmet çalışanları pencere nesnesine doğrudan erişemez. Bu nedenle, değerleri depolamak için window.localStorage kullanamazlar. Ayrıca hizmet işçileri kısa ömürlü yürütme ortamlarıdır. Kullanıcının tarayıcı oturumu boyunca tekrar tekrar sonlandırılırlar. Bu da onları global değişkenlerle uyumsuz hale getirir. Bunun yerine, verileri yerel makinede depolayan chrome.storage.local seçeneğini kullanın.

Uzantı hizmet işçileri için diğer depolama alanı seçenekleri hakkında bilgi edinmek üzere Küresel değişkenler kullanmak yerine verileri kalıcı hale getirme başlıklı makaleyi inceleyin.

5. adım: Etkinliklerinizi kaydedin

Tüm etkinlik dinleyicilerinin, hizmet çalışanının genel kapsamına statik olarak kaydedilmesi gerekir. Diğer bir deyişle, etkinlik dinleyicileri eşzamansız işlevlere yerleştirilmemelidir. Bu sayede Chrome, servis çalışanı yeniden başlatılırsa tüm etkinlik işleyicilerinin geri yüklenmesini sağlayabilir.

Bu örnekte chrome.omnibox API'sini kullanacağız ancak önce manifest'te her şey bir arada kutusu anahtar kelime tetikleyicisini beyan etmemiz gerekir:

manifest.json:

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

Ardından, komut dosyasının üst düzeyinde her şey bir arada kutusu etkinlik işleyicilerini kaydedin. Kullanıcı, adres çubuğuna çok amaçlı adres çubuğu anahtar kelimesini (api) ve ardından sekme veya boşluk tuşunu girdiğinde Chrome, depolama alanındaki anahtar kelimelere göre öneriler listesi gösterir. Mevcut kullanıcı girişini ve bir suggestResult nesnesini alan onInputChanged() etkinliği, bu önerileri doldurmaktan sorumludur.

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);
});

Kullanıcı bir öneri seçtikten sonra onInputEntered(), ilgili Chrome API referans sayfasını açar.

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() işlevi, her şey bir arada kutusundaki girişi alır ve storage.local alanına kaydeder. Bu sayede en son arama terimi daha sonra çok amaçlı adres çubuğu önerisi olarak kullanılabilir.

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. adım: Düzenli etkinlik oluşturun

setTimeout() veya setInterval() yöntemleri, genellikle gecikmeli veya periyodik görevleri gerçekleştirmek için kullanılır. Ancak planlayıcı, hizmet çalışanı sonlandırıldığında zamanlayıcıları iptal edeceğinden bu API'ler başarısız olabilir. Bunun yerine uzantılar chrome.alarms API'sini kullanabilir.

Manifest dosyasında "alarms" iznini isteyerek başlayın. Ayrıca, uzak bir ana makinede barındırılan uzantı ipuçlarını almak için ana makine izni istemeniz gerekir:

manifest.json:

{
  ...
  "permissions": ["storage"],
  "permissions": ["storage", "alarms"],
  "host_permissions": ["https://chrome.dev/f/*"],
}

Uzantı, tüm ipuçlarını getirir, rastgele bir ipucu seçer ve depolama alanına kaydeder. İpucunu güncellemek için günde bir kez tetiklenecek bir alarm oluştururuz. Chrome'u kapattığınızda alarmlar kaydedilmez. Bu nedenle, alarmın mevcut olup olmadığını kontrol etmemiz ve yoksa oluşturmamız gerekiyor.

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. Adım: Diğer bağlamlarla iletişime geçme

Uzantılar, sayfanın içeriğini okumak ve değiştirmek için içerik komut dosyalarını kullanır. Kullanıcı bir Chrome API referans sayfasını ziyaret ettiğinde, uzantının içerik komut dosyası sayfayı günün ipucu ile günceller. Hizmet çalışanından günün bahşişini istemek için bir mesaj gönderir.

Manifest dosyasında içerik komut dosyasını tanımlayarak başlayın ve Chrome API referans dokümanlarına karşılık gelen eşleme desenini ekleyin.

manifest.json:

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

Yeni bir içerik dosyası oluşturun. Aşağıdaki kod, hizmet işçisine ipucu isteğinde bulunan bir mesaj gönderir. Ardından, uzantı ipucunu içeren bir pop-up açan bir düğme ekler. Bu kod, yeni web platformu Popover API'yi kullanır.

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;
}

Son adım, servis işleyicimize günlük ipucunu içeren bir yanıt gönderen bir mesaj işleyici eklemektir.

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;
  }
});

İşlevini test edin

Projenizin dosya yapısının aşağıdaki gibi göründüğünü doğrulayın:

Uzantı klasörünün içeriği: resimler klasörü, manifest.json, service-worker.js, sw-omnibox.js, sw-tips.js ve content.js

Uzantınızı yerel olarak yükleme

Paketlenmemiş bir uzantıyı geliştirici modunda yüklemek için Merhaba dünya başlıklı makaledeki adımları uygulayın.

Referans sayfasını açma

  1. Tarayıcının adres çubuğuna "api" anahtar kelimesini girin.
  2. "Sekme" veya "boşluk" tuşuna basın.
  3. API'nin tam adını girin.
    • VEYA geçmiş aramalar listesinden seçim yapın
  4. Chrome API referans sayfası yeni bir sayfada açılır.

Aşağıdaki gibi görünmelidir:

Çalışma zamanı API&#39;si referansını açan Hızlı API Referansı
Çalışma zamanı API'sini açan hızlı API uzantısı.

Günün ipucunu açma

Uzantı ipucunu açmak için gezinme çubuğundaki İpucu düğmesini tıklayın.

Günlük ipucunu şuradan açabilirsiniz:
Günün ipucunu açan hızlı API uzantısı.

🎯 Olası geliştirmeler

Bugün öğrendiklerinizi kullanarak aşağıdakilerden birini yapmayı deneyin:

  • Her şey bir arada kutusu önerilerini uygulamanın başka bir yolunu keşfedin.
  • Uzatma ipucunu görüntülemek için kendi özel modal pencerenizi oluşturun.
  • MDN'nin Web Uzantıları referans API sayfalarına ek bir sayfa açın.

Kanalınızı geliştirmeye devam edin.

Bu eğitim kursunu tamamladığınız için tebrikler 🎉. Yeni başlayanlar için diğer eğitim kurslarını tamamlayarak becerilerinizi geliştirmeye devam edin:

Uzantı Öğrenecekleriniz
Okuma süresi Belirli bir sayfa grubuna otomatik olarak öğe eklemek için.
Sekme Yöneticisi Tarayıcı sekmelerini yöneten bir pop-up oluşturmak için.
Odak modu Uzantı işlemini tıkladıktan sonra mevcut sayfada kod çalıştırmak için.

Keşfetmeye devam et

Uzantı hizmet işçisi öğrenme yolunuza devam etmek için aşağıdaki makaleleri incelemenizi öneririz: