PWA, aslında tamamen mobil cihazlar için tasarlanmış hız ve performans odaklı web uygulamalarıdır. PWA yapısına uygun tasarlanmış olan siteler mobil cihazınızın anasayfasına direkt bir mobil uygulama gibi kayıt edilmesini sağlamakta ve native bir mobil uygulamada olan (çevrimdışı erişim ve push bildirimleri gibi özellikler de dahil) birçok özelliği desteklemektedir. Şimdi sizlere popülerliği her geçen gün artan React programlama dili ile PWA tabanlı bir sitenin nasıl gerçekleştirildiği ile alakalı bilgi paylaşımında bulunacağız.
1. Kurulumların Gerçekleştirilmesi:Öncelikle create-react-app komutu kullanılarak aşağıdaki şekilde basit bir React uygulamasının oluşturulması gerekmektedir.
#npm init ile package.json dosyası yoksa oluşturulması npm init #npm ile create-react-app modülünün yüklenmesi npm install -g create-react-app #create-react-app ile yeni uygulama oluşturulması create-react-app ornek-pwa-uygulamasiYukarıdaki komutun çalıştırılması ile birlikte aşağıdaki şekilde bir ekran görüntüsü oluşacaktır.
Sonrasında link yönlendirmelerini gerçekleştirebilmemiz için React-Router modülü aşağıdaki şekilde kuralım.
cd ornek-pwa-uygulamasi #react-router modulunun kurulması npm install --save [email protected]Daha sonra hazırlanan proje kodunda src dizini içine girilerek App.js dosyasının aşağıdaki kodlara göre güncellenmesi gerekmektedir.
#src dizini içerisine girin. cd src #App.js dosyası içerisine asagıdaki kodu yapıştırın. import React, { Component } from 'react'; import { Router, browserHistory, Route, Link } from 'react-router'; import logo from './logo.svg'; import './App.css'; const Page = ({ title }) => ( <div className="App"> <div className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h2>{title}</h2> </div> <p className="App-intro"> Bu {title} sayfasıdır. </p> <p> <Link to="/">Anasayfa</Link> </p> <p> <Link to="/hakkinda">Hakkında</Link> </p> <p> <Link to="/ayarlar">Ayarlar</Link> </p> </div> ); const Anasayfa = (props) => ( <Page title="Anasayfa"/> ); const Hakkinda = (props) => ( <Page title="Hakkinda"/> ); const Ayarlar = (props) => ( <Page title="Ayarlar"/> ); class App extends Component { render() { return ( <Router history={browserHistory}> <Route path="/" component={Anasayfa}/> <Route path="/hakkinda" component={Hakkinda}/> <Route path="/ayarlar" component={Ayarlar}/> </Router> ); } } export default App;Son olarak npm start komutunu çalıştırarak projenin 3000 portu üzerinden çalışmasını sağlayabilirsiniz.
#projenin çalıştırılması npm start2. Lighthouse Chrome Plugin Kurulumu:
LightHouse Google tarafından geliştiriciler için oluşturulmuş, sitenizi PWA tabanlı hazırlamak için yararlanabileceğiniz bir araçtır. Sağladığı birçok yarar bulunmaktadır. Geliştirme süresince tool üzerinden eksik kalan konularla alakalı geri bildirimleri alabilirsiniz.
Öncelikle Lighthouse uzantısını Chromenuza linke tıklayarak yükleyiniz. Sonrasında browserinizde açılmış olan http://localhost:3000 sayfasının olduğu taba geçiniz ve LightHouse uzantısında bulunan Generate Reports butonuna tıklayınız. Açılan popup dialogta sitenizin PWA yapısına uyum durumu hakkında progressive bar gözükecektir.
Yukarıdaki resimde görüldüğü üzere PWA için yapılması ve izlenmesi gereken adımlarımız bulunmaktadır. Şimdi bunları adım adım gerçekleyelim;
3. Service Worker Kurulması:
Service worker uygulamamız ile network arasında bulunan bir javascript tabanlı köprü gibidir. Bu yapı kullanılarak network hataları veya alınan dosyaların cachelenmesi gibi durumların oluşturulması sağlanacaktır. Böylelikle offline çalışma yapısına uygun bir kurguda bu worker sayesinde tanımlanabilecektir. Yapılması gereken adımlar şu şekildedir;
- public dizini altında service-worker.js dosyası oluşturmak,
- service worker dosyasını index.html dosyasına kayıt etmek,
- Cacheleme mekanizmasının kurulması
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> <title>React Uygulaması</title> </head> <body> <div id="root"></div> <script> if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('service-worker.js').then(function(registration) { console.log('ServiceWorker registration successful with scope: ', registration.scope); }, function(err) { console.log('ServiceWorker registration failed: ', err); }).catch(function(err) { console.log(err) }); }); } else { console.log('service worker is not supported'); } </script> </body> </html>Son olarak cache mekanizmasının hazırlanması kaldı. Aşağıdaki kod parçacığını daha önceden oluşturduğumuz service.workers.js dosyası içerisine yapıştıralım.
var doCache = false; var CACHE_NAME = 'my-pwa-cache-v1'; self.addEventListener("activate", event => { const cacheWhitelist = [CACHE_NAME]; event.waitUntil( caches.keys().then(keyList => Promise.all(keyList.map(key => { if (!cacheWhitelist.includes(key)) { console.log('Deleting cache: ' + key) return caches.delete(key); } })) ) ); }); self.addEventListener('install', function(event) { if (doCache) { event.waitUntil( caches.open(CACHE_NAME) .then( function(cache) { fetch("asset-manifest.json") .then(response => { response.json() }) .then(assets => { const urlsToCache = [ "/", assets["main.js"] ] cache.addAll(urlsToCache) console.log('cached'); }) }) ); } }); self.addEventListener('fetch', function(event) { if (doCache) { event.respondWith( caches.match(event.request).then( function(response) { return response || fetch(event.request); }) ); } });Şimdi tekrardan Lighthouse pluginini çalıştırıp generate report ile son durumu gözlemleyelim.
Yukarıdaki resimde de gördüğünüz gibi service worker ile alakalı hata giderilmiş oldu. Halen caching ile alakalı hata gözükmekte ancak bunun sebebi halen uygulamada cache mekanizmasını çalışır hale getirmedik. Bunu çalışır duruma getirmemiz ile birlikte bu hata listeden kalkacaktır.
4. Javascript yüklenmeden çalışma yöntemi eklenmesi:
Şimdi sıra sitenize giriş yapıldığı anda Javascript yüklenmesine gerek kalmaksızın sitenin çalışırlığının sağlanmasında. Şimdi index.html sayfamızın içerikleri javascript ile doldurulmaktadır. Bunun öncesinde React ile içeriğin doldurulması yerine html ve css ile sayfanın boş gelmesi engellenecektir. Aşağıdaki kod satırını kopyalarak içeriği ayarlayalım.
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> <title>React Uygulaması</title> <!-- Add in some basic styles for our HTML --> <style type="text/css"> body { margin: 0; padding: 0; font-family: sans-serif; } .App { text-align: center; } .App-header { background-color: #222; height: 150px; padding: 20px; color: white; } .App-intro { font-size: large; } </style> </head> <body> <!-- Filler HTML as our app starts up --> <div id="root"> <div class="App"> <div class="App-header"> <h2>Home</h2> </div> <p class="App-intro"> Site yükleniyor.. </p> </div> <script> if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('service-worker.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }, function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }).catch(function(err) { console.log(err) }); }); } else { console.log('service worker is not supported'); } </script> </body> </html>5. Siteye mobil uygulama özelliği kazandırılması:
Burada yapılacak çalışma sonrasında sitenizi ziyaret eden kullanıcı websitenizi mobil bir uygulama gibi telefonunun anasayfasına kayıt edebilecektir. Yapılması gereken ilk şey public dizini altında manifest.json dosyasını oluşturmanız ve aşağıdaki içeriğin kopyalanmasıdır.
{ "short_name": "İlk PWA Uygulamam", "name": "İlk Progressive Web Uygulamam", "icons": [ { "src":"icon.png", "sizes": "192x192", "type": "image/png" } ], "start_url": "/?utm_source=homescreen", "background_color": "#222", "theme_color": "#222", "display": "standalone" }icon.png dosyasının boyutu 192x192 şeklinde olmalıdır.
manifest.json dosyasını ve icon.png dosyasını public dizini altına koyduktan sonra index.html dosyasının header kısmını aşağıdaki şekilde güncelleyelim.
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> <!-- manifest dosyasını tanımla --> <link rel="manifest" href="%PUBLIC_URL%/manifest.json"> <!-- Browsera PWA uyumlu olduğunu söyle --> <meta name="mobile-web-app-capable" content="yes"> <!-- iOS'a PWA uyumlu olduğunu söyle --> <meta name="apple-mobile-web-app-capable" content="yes"> <!-- Tema renginin tanımlı olduğundan emin ol --> <meta name="theme-color" content="#536878"> <title>React Uygulaması</title>6. Firebase Üzerinde Uygulamanın Çalıştırılması:
Son olarak uygulama artık PWA yapısına uygun hale getirilmiştir. Şimdi yapılması gereken uygulamamızı canlıya almak. Öncelikle uygulamanın cache mekanizmasını service-worker.js dosyasında bulunan doCache = false satırını true olarak setleyerek aktif hale getirelim. Sonrasında Firebase Konsoluna gidip orada yeni bir uygulama oluşturalım. Daha sonra komut satırına gidip aşağıdaki kodlamaları çalıştıralım.
#firebase-tools indirilmesi npm install -g firebase-tools #firebase modülüne giriş firebase login #firebase tabanlı proje oluşturulması firebase init #firebasede projenin canlıya atılması npm run build && firebase deploy