Man patinka kurti įrankius, kurie ne tik veikia - jie Mano komanda jau pakankamai ilgai yra „Next.js“ trenkuose, kad tiksliai žinotų, kas skauda. - Drop-in paketas, kuris prijungia visą PWA palaikymą jūsų Next.js programoje be plaukų plyšimo. Išeikite iš savo kelio next-pwa-pack The Backstory (dar žinomas kaip „Kodėl aš parašiau šį dalyką“) Kiekvieną kartą, kai klientas paminėjo „PWA palaikymą“, aš apkabinau save. Aš išbandžiau esamas bibliotekas. Per daug magija. tonų konfig. Arba tiesiog visiškai nesuderinamas su - kuris, beje, mes visiškai priėmė. norėjau: App Router Serverio pusės cache atkūrimas. „App Router“ integracija. Lengva sinchronizacija tarp skirtukų. Švarus API, skirtas valdyti talpyklą iš "backend". Vietoj to, aš baigiau rašyti aptarnavimo darbuotojus rankomis. Tuning talpyklos TTLs. Sprendžiant atnaujinimo logiką. Valdyti stale klientus. Rankiniu būdu ištrinti talpyklas kiekvieną kartą, kai mes siuntėme. Ir net nesukelkite manęs pradėti vartotojams, kurie nemato atnaujinimų, kol jie sunkiai atnaujino. Man reikėjo kažko paprasto, nuspėjamo ir išbandyto mūšyje. pastatą Kas įėjo į jį Naujasis PvP paketas Naujasis PvP paketas Pirmasis žingsnis buvo parašyti minimalių paslaugų darbuotojas: HTML atmintinė su TTL. Statinio turto tvarkymas. Veikia neprisijungus, kaip turėtų būti tikra PWA. Tada pridėjau pranešimų sistemą, kad klientas galėtų kalbėtis su aptarnavimo darbuotoju, pavyzdžiui, ištrinti talpyklą arba visiškai išjungti talpyklą. Vėliau parašiau keletą scenarijų: Automatiškai kopijuokite sw.js, manifest.json ir offline.html į savo projektą. Įpurškite serverio veiksmą, vadinamą revalidatePWA, kurį galite naudoti bet kur (API maršrutai, serverio veiksmai, serverio komponentai - pasirinkite). Norėdami gauti visą "App Router" ir SSR / Edge palaikymą, aš supakuoju viską į aukštesnės tvarkos funkciją: Vienas importas, vienas skambutis – padaryta. withPWA Aš taip pat sukūriau skirtukų sinchronizavimą. nes vartotojai atidarykite savo programą 3 skirtukuose ir tikėkite, kad jie stebuklingai atnaujins sinchronizavimą. + Šaltinis Apie įvykius. Viliu localStorage storage Rezultatas? Paketas, kuris tiesiog veikia. Nėra juodosios magijos konfigūracijos. Nėra jūsų programos pagrindinių dalių perrašymo. Ką gaunate su next-pwa-pack Naujasis PvP paketas Kai įdiegsite, gausite: Paslaugų darbuotojo registracija iš dėžutės - be katilo plokštės. Nepriklausomas atgalinis ryšys su pritaikomu offline.html. Automatiškai nukopijuoti failai, kuriuos galite pataisyti (manifestas, SW ir kt.). "Cache" valdymo API - aiškiai, atnaujinti, išjungti, viskas programiniu būdu. Sinchronizavimas tarp skirtukų – nėra nuolatinio turinio kelių skirtukų nustatymuose. Plėtros skydelis realaus laiko PWA būsenai vietinės plėtros metu. Serverio pusės atnaujinimo palaikymas per serverio veiksmus, API maršrutus arba išorines webhook integracijas. Pakuotę galite įsigyti čia: https://github.com/dev-family/next-pwa-pack Kas atsitinka, kai jį įdiegiate Įdiegimo scenarijus automatiškai kopijuoja PWA boilerplate į : /public sw.js – jūsų paslaugų darbuotojas su talpyklos logika. „offline.html“ – atgalinis puslapis, skirtas neprisijungus. manifest.json – pakeiskite jį, kad jis atitiktų jūsų programą. ⚠️ Esami failai nebus perrašyti - tai gerbia jūsų diegimą. Jei norite paleisti kopiją rankiniu būdu: node node_modules/next-pwa-pack/scripts/copy-pwa-files.mjs # or npx next-pwa-pack/scripts/copy-pwa-files.mjs Serverio veikla Jis taip pat pridedamas prie jūsų arba Failas priklausomai nuo jūsų aplankų struktūros: revalidatePWA app/actions.ts src/app/actions.ts "use server"; export async function revalidatePWA(urls: string[]) { const baseUrl = process.env.NEXT_PUBLIC_HOST || "http://localhost:3000"; const res = await fetch(`${baseUrl}/api/pwa/revalidate`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ urls, secret: process.env.REVALIDATION_SECRET, }), }); return res.json(); } Jei šis failas neatsiranda, galite paleisti: node node_modules/next-pwa-pack/scripts/copy-pwa-server-actions.mjs Konfigūruokite savo Žymė: Jason Žymė: Jason Po įdiegimo nepamirškite pritaikyti : /public/manifest.json { "name": "My App", "short_name": "App", "description": "My amazing PWA app", "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#000000", "icons": [ { "src": "/icons/icon-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/icons/icon-512x512.png", "sizes": "512x512", "type": "image/png" } ] } Įdėkite savo ikonas į Arba pakreipti kelius aukščiau. nieko fancy. public/icons/ Greitasis paleidimas: Wire It Up Įdėkite savo dizainą į Ir magija įsijungia į: PWAProvider import { PWAProvider } from "next-pwa-pack"; export default function layout({ children }) { return <PWAProvider>{children}</PWAProvider>; } Jei norite, kad atnaujinimas veiktų iš serverio pusės, taip pat turėsite atnaujinti vidinę programinę įrangą: // /middleware.ts import { withPWA } from "next-pwa-pack/hoc/withPWA"; function originalMiddleware(request) { // your logic here return response; } export default withPWA(originalMiddleware, { revalidationSecret: process.env.REVALIDATION_SECRET!, sseEndpoint: "/api/pwa/cache-events", webhookPath: "/api/pwa/revalidate", }); export const config = { matcher: ["/", "/(ru|en)/:path*", "/api/pwa/:path*"], }; HOC pasirinkimo galimybės: originalMiddleware: jūsų pagrindinė tarpinė programinė įranga (pvz., i18n arba auth). revalidationSecret: slaptas žetonas, skirtas užrakinti talpyklos atnaujinimą. sseEndpoint: SSE srauto kelias (pakeisti, jei jis prieštarauja). webhookPath: galutinis taškas, skirtas išjungti talpyklos atnaujinimą (naudoja revalidatePWA). Viduje yra Pvp tiekėjas Pvp tiekėjas Tų pakabina daiktų krūvą po dangteliu - ir jūs taip pat galite išsirinkti vyšnių komponentus: PWAProvider RegisterSW Automatiškai registruoja tarnybos darbuotoją ( Greitai tvarko klaidas. Jei reikia, galite perkelti kelią: /sw.js <PWAProvider swPath="/custom/sw.js">{children}</PWAProvider> CacheCurrentPage Perima navigaciją (įskaitant SPA stiliaus perėjimus), užfiksuoja dabartinio puslapio HTML. SWRevalidateListener Laikrodžiai localStorage įvykiams ir sukelia talpyklos atnaujinimą tarp skirtukų. SSERevalidateListener Siunčia serverio siunčiamus įvykius iš Kai jūsų atsarginė pusė sako „iš naujo patvirtinkite šiuos URL“, šis klausytojas užtikrina, kad klientai tai padarytų. sseEndpoint DevPWAStatus Dev-only panel galite įjungti taip: <PWAProvider devMode>{children}</PWAProvider> Parodų : Online / Offline statusas Cache versija Atnaujinti prieinamumą Vieno paspaudimo įrankiai: išvalyti talpyklą, neregistruoti SW, atnaujinti, išjungti / įgalinti talpyklą Ką darbuotojas iš tikrųjų daro Pagrindinė Rankšluosčiai : sw.js HTML įkrovimas Puslapiai talpinami naudojant TTL (pagal numatytuosius nustatymus: 10 min. – keičiami sw.js) Automatinis patvirtinimas, kai pasibaigia TTL Atsisiųskite failą, jei trūksta HTML Statinis turtas JS, CSS, vaizdai yra talpinami amžinai Tik talpyklos gauna prašymus Palaikymo žinutės Šiuos veiksmus palaiko klientas: CACHE_CURRENT_HTML Paslaugos Rekomenduojama - URL DISABLE_CACHE / Įjungti / Įjungti Laukimas / Laukimas CLEAR_STATIC_CACHE Išsaugoti Offline mados Tarnauja offline.html, jei tiek tinklo, tiek talpyklos gedimas Stengiasi atsipalaiduoti, kai grįžta į internetą Naudoti Vidurinėje dalyje išpjauti išpjauti Štai kur Ji atneša talpyklos atnaujinimą į SSR ir Edge Middleware - su SSE palaikymu ir visa tai. next-pwa-pack export default withPWA(originalMiddleware, { revalidationSecret: process.env.REVALIDATION_SECRET!, sseEndpoint: "/api/pwa/cache-events", webhookPath: "/api/pwa/revalidate", }); Params: originalMiddleware: jūsų esama middleware logika (auth, i18n ir kt.) revalidationSecret: kad niekas kitas negalėtų ištrinti jūsų talpyklos sseEndpoint: perkrauti, jei kažkas kitas naudoja šį maršrutą webhookPath: naudojamas serverio arba išorinių sistemų tam tikrų URL patvirtinti Realaus pasaulio naudojimo atvejai Cache atnaujinimas po duomenų pasikeitimų import { updateSWCache } from "next-pwa-pack"; // After creating a blog post: const handleCreatePost = async (data) => { await createPost(data); updateSWCache(["/blog", "/dashboard"]); }; Cache atnaujinimas iš serverio import { revalidatePWA } from "../actions"; await createPost(data); await revalidatePWA(["/my-page"]); Išvalyti talpyklą Logout import { clearAllCache } from "next-pwa-pack"; const handleLogout = async () => { await logout(); await clearAllCache(); router.push("/login"); }; Visi kliento cache veiksmai import { clearAllCache, reloadServiceWorker, updatePageCache, unregisterServiceWorkerAndClearCache, updateSWCache, disablePWACache, enablePWACache, clearStaticCache, usePWAStatus, } from "next-pwa-pack"; // Examples: await clearAllCache(); await reloadServiceWorker(); await updatePageCache("/about"); await unregisterServiceWorkerAndClearCache(); await clearStaticCache(); updateSWCache(["/page1", "/page2"]); disablePWACache(); enablePWACache(); const { online, hasUpdate, swInstalled, update } = usePWAStatus(); API maršrutas išoriniam talpyklos sukėlimui Jei norite išjungti talpyklos atnaujinimus iš išorės (pvz., iš administravimo skydo), čia yra API maršrutas, kurį galite naudoti: // app/api/webhook/revalidate/route.ts import { NextRequest, NextResponse } from "next/server"; import { revalidatePWA } from "@/app/actions"; import { revalidateTag } from "next/cache"; import { FetchTags } from "@/app/api/endpoints/backend"; export async function POST(request: NextRequest) { try { const { tags, secret, urls } = await request.json(); if (secret !== process.env.REVALIDATION_SECRET) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const validTags = Object.values(FetchTags); const invalidTags = tags?.filter((tag) => !validTags.includes(tag)) || []; if (invalidTags.length > 0) { return NextResponse.json( { error: `Invalid tags: ${invalidTags.join(", ")}` }, { status: 400 } ); } let successful = 0; let failed = 0; if (tags?.length) { const tagResults = await Promise.allSettled( tags.map((tag) => revalidateTag(tag)) ); successful = tagResults.filter((r) => r.status === "fulfilled").length; failed = tagResults.filter((r) => r.status === "rejected").length; } if (urls?.length) { await revalidatePWA(urls); } return NextResponse.json({ success: true, message: "Cache revalidation completed", tags, urls, successful, failed, timestamp: new Date().toISOString(), }); } catch (error) { console.error("Webhook revalidation error:", error); return NextResponse.json({ error: "Internal server error" }, { status: 500 }); } } Paspauskite jį su: POST https://your-app.com/api/webhook/revalidate { "tags": ["faq"], "secret": "1234567890", "urls": ["/ru/question-answer"] } Debugging ir DevTools Štai ką galite patikrinti atliekant debuggingą: Eikite į DevTools → Application → Service Workers. Patvirtinkite, kad darbuotojas yra registruotas. Patikrinkite talpyklą → html-cache-v2, kad pamatytumėte, ar puslapiai yra talpyklos. Simuliuokite neprisijungus tinkle → neprisijungus ir iš naujo įkelkite. Console logs from the service worker help too: [PWA] Service Worker registered [SW] Cached: /about [SW] Revalidated and updated cache for: /blog Gotchas & Pastabos Keletas dalykų, kuriuos turėtumėte žinoti prieš plaukdami: Saugumas PWA gamyboje reikalingas HTTPS. Tik GET prašymai yra talpinami. Neslėpkite slaptų duomenų. Veikla Pakuotė nepalies jūsų programos našumo bazinės linijos. Tai žymiai pagerina pasikartojančias apkrovas. Konfigūracija TTL yra nustatytas sw.js (numatytas laikas: 10 minučių). Galite pašalinti URL iš talpyklos naudojant CACHE_EXCLUDE. manifest.json turi būti pritaikytas jūsų programai. revalidatePWA veiksmas yra redaguojamas – pritaikykite jį pagal poreikį. withPWA ir PWAProvider priima šias parinktis: export default function PWAProvider({ children, swPath, devMode = false, serverRevalidation = { enabled: true, sseEndpoint: "/api/pwa/cache-events" }, }: PWAProviderProps) { Kas bus toliau Parašyta už Jis turėtų dirbti ant Taip pat - tik ne išsamiai išbandytas. next-pwa-pack Next.js 15 Next.js 13 App Router Planuojamos savybės: TTL konfigūracija per parinktis (be redagavimo sw.js) Push pranešimai Pattern-based cache kontrolė Veiksmingumo metrikos, skirtos talpyklos efektyvumui Tai ir yra. Jei pavargote rankiniu būdu ginčytis su paslaugų darbuotojais, suteikite Jūs pereisite nuo nulio iki visiško PWA palaikymo per vieną kavos pertrauką. next-pwa-pack Klausimai, klaidos ar atsiliepimai? Atidarykite problemą arba susisiekite su mumis. github.com/dev šeima/next-pwa-pack