Hizmet işçileriyle etkinlikleri işleme

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

Genel Bakış

Bu eğitimde, Chrome uzantısı hizmet çalışanları tanıtılmaktadır. Bu eğitimin bir parçası olarak, kullanıcıların çok amaçlı adres çubuğunu kullanarak Chrome API referans sayfalarına hızlıca gitmelerini sağlayan bir uzantı oluşturacaksınız. Bu kursta şunları öğreneceksiniz:

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

Başlamadan önce

Bu kılavuzda, temel web geliştirme deneyimine sahip olduğunuz varsayılmaktadır. Uzantı geliştirmeye giriş için Extensions 101 (Uzantılara Giriş) ve Hello World (Merhaba Dünya) dokümanlarını incelemenizi öneririz.

Uzantıyı oluşturma

Uzantı dosyalarını tutmak için quick-api-reference adlı yeni bir dizin oluşturarak başlayın veya kaynak kodunu GitHub örnekleri depomuzdan indirin.

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

Projenin kök dizininde 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 çalışanlarını yalnızca tek bir JavaScript dosyası gerektiren manifestte kaydeder. Web sayfasında olduğu gibi navigator.serviceWorker.register() işlevini çağırmanız gerekmez.

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

Manifestteki uzantının meta verileri ve simgeleri hakkında daha fazla bilgi edinmek için Okuma süresi eğitiminin ilk adımlarına göz atın.

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

Hizmet çalışanımız iki özelliği uygular. Daha iyi bakım için her özelliği ayrı bir modülde uygulayacağız. Öncelikle, hizmet çalışanımızı manifestimizde ES Modülü olarak bildirmemiz gerekir. Bu, hizmet çalışanımıza modül 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ında birden fazla dosyayı içe aktarmanın diğer yolları hakkında bilgi edinmek için Komut dosyalarını içe aktarma bölümüne bakın.

İ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 öğreneceğinizi açıklayacağım. Öncelikle Paketlenmemiş bir uzantıyı yükleme talimatlarını uygulayın.

30 saniye sonra "service worker (inactive)" (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ı (inactive)" bağlantısını tıklayın. Bu durum aşağıdaki animasyonda gösterilmektedir.

Hizmet çalışanını incelemenin onu uyandırdığını fark ettiniz mi? Geliştirici araçlarında hizmet çalışanını açmak, hizmet çalışanının etkin kalmasını sağlar. Hizmet çalışanınız sonlandırıldığında uzantınızın doğru şekilde çalıştığından emin olmak için Geliştirici Araçları'nı kapatmayı unutmayın.

Şimdi, hataların nerede olduğunu öğrenmek için uzantıyı kesintiye uğratın. Bunu yapmanın bir yolu, service-worker.js dosyasındaki './sw-omnibox.js' içe aktarma işleminden ".js"yi silmektir. Chrome, hizmet çalışanını kaydedemez.

chrome://extensions sayfasına geri dönün ve 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ı hizmeti çalışanıyla ilgili hata ayıklamanın diğer yolları için Uzantılarda hata ayıklama başlıklı makaleyi inceleyin.

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

Chrome, gerekmediğinde hizmet çalışanlarını kapatır. Hizmet çalışanı oturumları arasında durumu korumak için browser.storage API'sini kullanırız. Depolama alanına erişim için manifest dosyasında izin isteğinde bulunmamız 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
browser.runtime.onInstalled.addListener(({ reason }) => {
  if (reason === 'install') {
    browser.storage.local.set({
      apiSuggestions: ['tabs', 'storage', 'scripting']
    });
  }
});

Service worker'lar window nesnesine doğrudan erişemez ve bu nedenle değerleri depolamak için window.localStorage kullanamaz. Ayrıca, hizmet çalışanları kısa ömürlü yürütme ortamlarıdır. Kullanıcının tarayıcı oturumu boyunca tekrar tekrar sonlandırıldıkları için genel değişkenlerle uyumlu değildirler. Bunun yerine, verileri yerel makinede depolayan browser.storage.local özelliğini kullanın.

Uzantı hizmeti çalışanları için diğer depolama seçenekleri hakkında bilgi edinmek üzere Genel 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. Başka bir deyişle, etkinlik işleyicileri asenkron işlevlere yerleştirilmemelidir. Bu sayede Chrome, hizmet çalışanı yeniden başlatıldığında tüm etkinlik işleyicilerin geri yüklendiğinden emin olabilir.

Bu örnekte browser.omnibox API'yi kullanacağız ancak önce manifestte çok amaçlı adres çubuğu anahtar kelime tetikleyicisini tanımlamamız gerekiyor:

manifest.json:

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

Şimdi, komut dosyasının en üst düzeyinde çok amaçlı adres çubuğu etkinlik işleyicilerini kaydedin. Kullanıcı, adres çubuğuna çok amaçlı adres çubuğu anahtar kelimesini (api) girip ardından sekme veya boşluk tuşuna bastığında Chrome, depolama alanındaki anahtar kelimelere dayalı bir öneri listesi gösterir. Bu önerileri doldurmaktan, mevcut kullanıcı girişini ve suggestResult nesnesini alan onInputChanged() etkinliği 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
browser.omnibox.onInputChanged.addListener(async (input, suggest) => {
  await browser.omnibox.setDefaultSuggestion({
    description: 'Enter a Chrome API or choose from past searches'
  });
  const { apiSuggestions } = await browser.storage.local.get('apiSuggestions');
  const suggestions = apiSuggestions.map((api) => {
    return { content: api, description: `Open browser.${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
browser.omnibox.onInputEntered.addListener((input) => {
  browser.tabs.create({ url: URL_CHROME_EXTENSIONS_DOC + input });
  // Save the latest keyword
  updateHistory(input);
});

updateHistory() işlevi, çok amaçlı adres çubuğu girişini alır ve storage.local'e 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 browser.storage.local.get('apiSuggestions');
  apiSuggestions.unshift(input);
  apiSuggestions.splice(NUMBER_OF_PREVIOUS_SEARCHES);
  return browser.storage.local.set({ apiSuggestions });
}

6. adım: Düzenli etkinlik oluşturma

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

Manifest dosyasında "alarms" iznini isteyerek başlayın:

manifest.json:

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

Uzantı, tüm ipuçlarını getirir, rastgele birini 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 mevcut değilse 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 browser.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 browser.alarms.get(ALARM_NAME);
  if (typeof alarm === 'undefined') {
    browser.alarms.create(ALARM_NAME, {
      delayInMinutes: 1,
      periodInMinutes: 1440
    });
    updateTip();
  }
}

createAlarm();

// Update tip once a day
browser.alarms.onAlarm.addListener(updateTip);

7. adım: Diğer bağlamlarla iletişim kurun

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 ipucuyla günceller. Hizmet çalışanından günün ipucunu istemek için bir mesaj gönderir.

Öncelikle içerik komut dosyasını manifest dosyasında tanımlayın ve Chrome API referans belgelerine karşılık gelen eşleşme kalıbını 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, bahşiş isteğinde bulunan hizmet çalışanına bir mesaj gönderir. Ardından, uzantı ipucunu içeren bir popover açacak 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 browser.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, hizmet çalışanımıza günlük ipucunu içerik komut dosyasına yanıt olarak gönderen bir ileti işleyici eklemektir.

sw-tips.js:

...
// Send tip to content script via messaging
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.greeting === 'tip') {
    browser.storage.local.get('tip').then(sendResponse);
    return true;
  }
});

Çalıştığını test etme

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: images 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 Hello world 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ş arama listesinden seçim yapın.
  4. Chrome API referans sayfasının bulunduğu yeni bir sayfa açılır.

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

Çalışma zamanı API 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ğunda bulunan İpucu düğmesini tıklayın.

Günlük ipucunu açma
Günün ipucunu açan hızlı API uzantısı.

🎯 Olası iyileştirmeler

Bugün öğrendiklerinize dayanarak aşağıdakilerden herhangi birini yapmaya çalışın:

  • Omnibox önerilerini uygulamanın başka bir yolunu keşfedin.
  • Uzantı ipucunu göstermek için kendi özel kalıcı öğenizi oluşturun.
  • MDN'nin Web Uzantıları referans API sayfalarına ek bir sayfa açın.

Gelişmeye devam edin.

Bu eğitimi tamamladığınız için tebrikler 🎉. Diğer başlangıç seviyesi eğitimlerini 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.
Konsantrasyon Modu Uzantı işlemi tıklandıktan sonra geçerli sayfada kod çalıştırmak için.

Keşfetmeye devam edin

Uzantı hizmet çalışanı öğrenme rotanıza devam etmek için aşağıdaki makaleleri incelemenizi öneririz: