Aceasta este o urmărire a mea postarea anterioară despre construirea unui PWA cu create-react-app (CRA). În postarea legată, am discutat despre modul în care am putea construi un Service Worker (SW) personalizat în timp ce rămânem în shell-ul create-react-app.

Dacă ați urmat împreună cu postarea (și sperăm că ați funcționat), ați fi observat un defect critic. Este încă extrem de greu să dezvolți un SW într-un mediu de dezvoltare. În esență, ar trebui să vă modificați codul SW, să rulați un proces de compilare, să-l testați, să rezolvați orice erori, să reîmprospătați și să repetați. Vorbind din experiență, este un proces epuizant.

Să mergem mai departe și să ne dăm seama cum să rezolvăm această problemă.

Lucrul în modul Dev

Bine, deci cum obținem un SW care rulează în modul dev, astfel încât să putem scrie rapid un cod greșit și să ne dăm seama ce funcționează și ce nu?

În primul rând, să ne dăm seama de ce nu funcționează în modul de dezvoltare. Creați un nou proiect CRA și deschideți registerServiceWorker.js sub src director.

În esența de mai sus, am doar codul relevant. Veți observa o verificare condiționată process.env.NODE_ENV === 'production'. Aceasta verifică dacă rulați o versiune de producție. Dacă nu executați o versiune de producție, SW va fi înlocuit cu un fișier fără opțiuni.

Raționamentul din spatele acestei decizii este prezentat în acest document Problema GitHub.

Mai întâi, încercați să fugiți yarn start în aplicația dvs. și verificați dacă există un fișier SW în fereastra barei de instrumente. Dacă faceți clic pe service-worker.js din bara de instrumente, vi se va afișa următorul fișier:

Din fericire, există o soluție simplă pentru acest lucru. Este un proces ușor în doi pași.

În primul rând, în interiorul registerServiceWorker.js fișier, căutați fișierul window.addEventListener('load') apel de funcție. Prima linie este o declarație pentru swUrl care spune:

const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;

Redenumiți fișierul service-worker parte din el cu orice altceva. Mă voi numi pe a mea service-worker-custom.js.

În al doilea rând, creați un fișier în directorul dvs. public cu exact același nume ca nume personalizat cu care tocmai ai venit. Deci, aș crea un fișier numit service-worker-custom.js în interiorul directorului public.

Acum, în interiorul service-worker-custom.js , plasează o declarație de jurnal simplă. Ceva asemănător cu: console.log('My custom service worker').

Acum, rulați din nou aplicația cu yarn start și ar trebui să vedeți declarația jurnal care apare în consola browserului. S-ar putea să trebuiască să anulați înregistrarea unui lucrător de service anterior dacă ați executat vreodată începerea firului înainte de aceasta.

Deci, iată-l. Un lucrător de service personalizat pe care îl puteți rula în siguranță în modul dev.

Notă: Nu este înțelept să testați un lucrător de service într-un program de dezvoltare în afara modului de navigare privată din browserul dvs. De asemenea, asigurați-vă întotdeauna că Actualizarea la reîncărcare este bifată în fereastra instrumentelor de dezvoltare atunci când testați în modul dev.

Combinând Dev și Prod

Acum, am aflat cum să testăm un SW în modul dev. Cu toate acestea, trebuie să găsim și o modalitate de a injecta codul nostru personalizat în SW generat de CRA într-o versiune de producție.

Dacă păstrați totul așa cum este cu configurațiile pe care le-am făcut până acum și rulați un proces de compilare și verificați construirea în browserul dvs., veți observa că fișierul SW generat este cel personalizat pe care l-am creat. Aceasta este o problemă, deoarece vrem să putem combina bunătatea a ceea ce ne oferă CRA cu propriul cod.

Putem face acest lucru cusw-precache bibliotecă. Am introdus această bibliotecă în postarea anterioară. Aici este Link GitHub la sw-precache bibliotecă.

Instalați biblioteca cu yarn add sw-precache . După ce ați făcut acest lucru, creați un sw-precache-config.js în directorul dvs. rădăcină. Iată fișierul meu:

Am introdus majoritatea acestui fișier în postarea anterioară. Singurul bit nou este importScripts opțiune. Acest lucru se explică de la sine, pur și simplu importă fișierul specificat de cale și încercăm să importăm fișierul SW personalizat.

Veți observa că calea fișierului nu are ./public prefix, deși fișierul este prezent în public director. Voi explica asta într-un pic.

Acum, actualizați package.json fișier cu o modificare a fișierului build comanda. Fă-ți build comandați următoarele:

react-scripts build && sw-precache --config=sw-precache-config.js

Acum, să ne întoarcem la calea fișierului pe care am furnizat-o la opțiunea importScripts. Dacă observați, sw-precache funcționează în esență ca un proces post build. Acum, dacă pur și simplu rulați un proces de compilare și deschideți directorul de construire care este creat, veți observa fișierul dvs. personalizat de serviciu în folderul de construire. Când oferim o cale către importScripts opțiune, o oferim în raport cu directorul de construire!

Odată ce ați făcut toate acestea, continuați și rulați versiunea de construire a aplicației dvs. și veți observa că declarația jurnal apare din nou în consola browserului.

Ei bine, iată-l! Acum puteți injecta un cod SW personalizat în SW implicit generat de CRA!