React ile Chrome Extension
Merhaba bu yazımda React kullanarak Chrome için bir web extension oluşturacağız. Chrome Storage Api’yi react custom hook ile kullanarak bir global state oluşturacağız. Hadi başlayalım. Github kodu makalenin sonunda mevcuttur.
Tarayıcı Uzantısı(Browser Extension) Nedir?
Internet taraycısı üzerinden(Chrome, Firefox vb) arka planda çalışan küçük uygulamadır. Bu uzantıların kullanımı çok geniştir. Örneğin istenilen herhangi bir web sayfası içerisine içerik ekleyebilir, yazım hataları kontrol edilip düzeltilebilir, çeviri işlemi yapılabilir ve tarayıcı daha effektive hale getirilebilir. Chrome Extenstion(Chromium tabanlı tüm tarayıcılar için buradan uzantı indirilebilir) ve Firefox Addons sayfalarından tarayıcınıza işinize yarayan bir sürü uzantı bulabilirsiniz
Extensionlar Nasıl Çalışır?
Konu hakkında bilginiz varsa bu bölümü geçip konuya direkt dalabilirsiniz.
Extensionlar; HTML,CSS, JavaScript, Resim gibi web sayflarında kullanılan dosyların sıkıştırılmış paketlerdir. Bu bir araya gelen dosyların extension olabilmesi için manifest dosyası gerekmektedir. Bu dosya json formantında olup extesion’ın nasıl çalışacağını, hangi sayfada çalışacağını, kısayol tuşu olup olmayağı gib bir sürü özelliği barındıran dosyadır.
Extension’ı tarayıcıya kurduktan sonra, adres çubunun sağ tarafında uzantının ikonu çıkar aşağıdaki gibi bir göreseldeki gibi birbirleriyle iletişim haline geçer.
Bileşenler:
background.js: Extension’ın tarayıcı üzerindeki olayları(event handler) yorumlayan dosya(lar)dır. Tarıyıcıda bir olay tetiklenene kadar uykuda kalır, tetiklendiğinde yapılması gereken işlemi yapar.Komut geldiğinde yüklenir komut bitince kaldırılır .
popup.html: Adres çubunun sağ tarafında uzantının ikonuna tıklayınca açılan pop sayfadır. Bu sayfa doğrudan ekranda açık olan web sayfasının içeriğine erişemez. Sayfaya ait localstorage bilgisine erişemez. Kendi ait localstorage bilgisi vardır.
popup.js: popup.html’le ait js dosyasıdır.
contentscript.js: Tarayıcının url bilgisindeki sayfasına içerik eklemek(sayfaya buton ekleme, Div ekleme vb) kullanılan javascript dosyasıdır. Sayfa yüklenirken, yüklendikten sonra ve uykuya geçitiğinde yüklenebilirler. Manifest dosyasında ayarlanara herangi bir URL için kısıtlanabilir ve tüm sayfalarda çalışması engellenebilir. Ziyaret edilen sayfanın bir ögesidir. Sayfaya ait localstorage’a ulaşabilir ve bacground.js ile popup veya options page’e bilgi aktarabilir.
options.html: Kullanıcıların extension’ı istedikleri şekilde konfigüre edebilmesi için kullanılan sayfadır. Yeni bir sekmede açılır.
Detaylı bilgi için
Senaryo
Google’ın arama sonuçları ekranına bir buton ekleyeceğiz ve kullanıcı bu butona basarak yapmış olduğu aramayı kaydedip; zaman içerisin bu aramaları tekrardan ziyaret edebilecek. Sayfaya eklenen button, popup.html ve options.html 3 tane componentimiz olacak. Bu componentlerin birbirileri ile iletişimlerini yazacağımız custom hook ile yaratıığımız global state ile yapacağız. Geliştirmenin sonucunda çıktısı şekilde olacak
Yeni react uygulaması yaratıp proje yapısını oluşturuyoruz. Proje yapısı aşağıdaki şekildedir.
components(1): Button, popup ve options sayfasına ait olan componentler
images(2): Geliştirmeden kullanılacak resim dosyaları
js(3): Componentlerimizi render eden dosyalar
pages(4): Componentlere ait HTML sayfalar
storage(5): Componetler arası iletişimi sağlayacak ve chrome.stroge api kullanan store’a ait dosyalar.
(6): Extension için kullanılacak ana dosyalar
webpack.config.js(7): React ile birlite gelen webpack configirasyonu yerine kullanacağımız dosyadır. Bu sayede tüm componentlerimizi kendi başına bundle bir dosya olarak oluşturucağız. Bütün büyü burada gerçekleşmektedir. Yukarıdaki resimde (1),(3) ve (4) ile gösterilen dosyaları, webpack dosyası kullanarak ayrı ayrı bundle dosyası haline getireceğiz. Yazının ilerleyen bölümlerinde bu dosya hakkında detaylı bilgi verilecektir.
Manifest.json
Örnek için dosyayı basit tuttum.
“background”(1): Tarayıcıda olacak tüm olayları dinleyen ve yorumlayan js dosyasının tanımlandığı kısımdır. İhtiyaca göre birden çok background java script dosyası olabilri.
“options-page” ve “action” (2): Option sayfasının ve popup sayfasının tanımlandığı kısımdır.
“permissions” (3): Extension’nın yetkilerinin tanımlandığı ve hangi sayfalarda çalışacağının tanımlandığı bölümdür.
Storage API
Kulllancı datalarını saklayan, getiren ve değişikleri takip eden API’dir. Bu api kullanabileceğimiz bir tane custom Hook yazacağız. Hook sayesinde yapılan işlemleri tutacağız hatta gizli pencerede de kullanılmasına izin vereceğiz.
Storage: Bilgileri storage’de hem localde hemde chrome sync ile çalışan sync olarak tutacağımız değişkenlerimizi tanımlıyoruz. Bu değişkenler verilerimizi Promise olarak storage’e kaydedip alabileceğiz.
useStorage: Kullanıcın girmiş olduğu bilgileri chrom.storage’a kaydeden ve ihtiyaç halinde getiren fonksiyondur. persisted özelliği ile gizli sekmelerde de kullanıcı verilerine erişim sağlıyoruz.
useStorageHook: Bilgileri storage kaydedecek hook’tur. 3 parametre almaktadır. Eğer kullanıcı bilgileri local’de tutmak isterse area:’local’ setlenmelidir. Eğer Chrome Sync kullanılacaksa area:’sync’ setlenmelidir.
Local ve Sync Hook: Uygulama içerisinde kullanacağımız Local ve Sync Hook fonksiyonları şu şekildedir.
Storage Hook’ın kullanımı:
Uygulama içerisinde kullanıcının arama geçmişini tutan ve uygulama ayarlarını tutan 2 tane store aşağıdaki gibi yaratıyoruz.
Componentler
Button: Arama sayfası yüklendikten sonra sayfaya ekleyeceğimiz componenttir.
Popup: Kullanıcın arama geçmişinin listelendiği sayfadır.
Options: Kullanıcın buttonun rengini, yazısını değiştirebileceği ayarların yapıldığı sayfadır.
Background script işlemleri:
Tanımladığımız button componentinin sayfa eklenmesi için kullandığımız scriptlerir.
background.js: Google arama sayfası yüklendikten sonra arama bölümündeki klavye butonun yanına yeni butonumuz için div’i yaratan inject_script.js ve oluşturduğumuz buttonu sayfaya ekleyen custom_button.bundle.js(bunu webpack oluşturuyor) ile scripti çalıştıran scripttir. manifest.json’da bu dosyanın çalıştırılması söylüyoruz. Yani bu dosyanın çalıştırılmasının sorumluluğu manifest dosyasına aittir.
Webpack Ayarları
Asıl büyünün döndüğü kısım burası. Oluşturduğumuz React Componentlerini ayrı ayrı bundle dosyaları olarak yaratıyoruz. Ortaya çıkan tüm dosyalar isteğe göre herhangi bir sayfaya dahil edilebilir. Örneğimizde button componenti sayfaya ekliyoruz. İlerde sayfaya panel ekleyenip arama geçmişi sayfanın içerisinde gösterilebilir. Şimde webpack dosyasına yakında bakalım. Gerekli açıklama dosyanın içerisinde commnet olarak bulunmaktadır.
Çalıştırma
Package.json dosyasında bulunan build:prod scriptini npm run build:prod ile çalıştırıyoruz.
Bu işlemin sonunda dist dosyasında webpack’in oluşturduğu dosyalar oluşacaktır.
Entension’ı developer modda çalıştıracağız.
- Dist dosyasının path’nı kopyalanır.
- Chrome uygulaması açılır
- Adres cubuğuna chrome://extensions/ yazılıp enter’a basılır.
- Açılan sayfada sağ üst köşede bulunan Developer Mode(Geliştirici Modu) aktif hale getirilir
- Sayfanın sağ üst köşesinde bulunan Load unpacked (Paketlenmemiş öğe yükle) butonu tıklanır ve dist dosyasının path’i yazılarak extension yüklenir.
Sonuç:
Kaynak kod:
Yeni yazıda görüşmek üzere