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 eğitimde ş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 rehberde, 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 kodu 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()'ı aramanı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ü içe aktarın

Hizmet çalışanımız iki özelliği uygular. Daha iyi bakım yapılabilmesi için her özelliği ayrı bir modülde uygulayacağız. Öncelikle, hizmet çalışanını manifestimizde ES Modülü olarak tanımlamamız 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 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 anlayacağınızı açıklayacağım. Öncelikle Paketlenmemiş bir uzantıyı yükleme talimatlarını uygulayın.

30 saniye sonra "service worker (inactive)" 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 etkinleştirdiğini fark ettiniz mi? Geliştirici araçlarında hizmet çalışanını açmak, hizmet çalışanını etkin tutar. 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ı ayırı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ında durumu korumak için chrome.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
chrome.runtime.onInstalled.addListener(({ reason }) => {
  if (reason === 'install') {
    chrome.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 chrome.storage.local'ı 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. Diğer 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 chrome.omnibox API'sini kullanacağız ancak önce manifest dosyasında ç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
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, çok amaçlı adres çubuğu girişini alır ve storage.local'a kaydeder. Böylece 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ş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 chrome.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 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şim kurun

Uzantılar, sayfanın içeriğini okumak ve değiştirmek için içerik komut dosyalarını kullanır. Bir kullanıcı 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ı manifestte bildirerek başlayı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'sini 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, hizmet çalışanımıza günlük ipucunu içerik komut dosyasına yanıt olarak 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;
  }
});

Ç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&#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 şurada aç:
Günün ipucunu açan hızlı API uzantısı.

🎯 Olası geliş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: