Μου αρέσει να φτιάχνω εργαλεία που δεν λειτουργούν μόνο Η ομάδα μου έχει βρεθεί στα τρενάκια του Next.js αρκετά καιρό για να γνωρίζει ακριβώς τι πονάει. - ένα πακέτο drop-in που συνδέει την πλήρη υποστήριξη PWA στην εφαρμογή Next.js χωρίς να ραγίζετε τα μαλλιά σας. Βγείτε από το δρόμο σας next-pwa-pack The Backstory (aka: Γιατί έγραψα αυτό το πράγμα) Κάθε φορά που ένας πελάτης ανέφερε «υποστήριξη PWA», χτύπησα τον εαυτό μου. Δοκίμασα υπάρχουσες βιβλιοθήκες. πάρα πολύ μαγεία. Τόνους διαμόρφωσης. Ή απλά εντελώς ασυμβίβαστη με - η οποία, παρεμπιπτόντως, έχουμε υιοθετήσει πλήρως. ήθελα: App Router Αναβάθμιση του server-side cache. Ενοποίηση App Router. Εύκολο συγχρονισμό μεταξύ των καρτών. Καθαρό API για τη διαχείριση της cache από το backend. Αντ 'αυτού, κατέληξα να γράφω υπαλλήλους εξυπηρέτησης με το χέρι. Προσαρμογή TTLs cache. Αντιμετώπιση της λογικής ενημέρωσης. Διαχείριση πελατών σταθερότητας. Και μην με κάνετε να ξεκινήσω σε χρήστες που δεν βλέπουν ενημερώσεις μέχρι να ανανεωθούν. Χρειαζόμουν κάτι απλό, προβλέψιμο και δοκιμασμένο στη μάχη. Κτίριο Τι μπήκε σε αυτό next-pwa-pack Επόμενο Πακέτο Το πρώτο βήμα ήταν να γράψετε έναν εργάτη μίνιμουμ υπηρεσιών: Χρησιμοποιήστε HTML με TTL. Διαχείριση στατικών περιουσιακών στοιχείων. Λειτουργεί εκτός σύνδεσης, όπως θα έπρεπε ένα πραγματικό PWA. Στη συνέχεια πρόσθεσα ένα σύστημα μηνυμάτων έτσι ώστε ο πελάτης να μπορεί να μιλήσει με τον υπάλληλο της υπηρεσίας - για παράδειγμα, να σπάσει μια προσωρινή μνήμη ή να απενεργοποιήσει εντελώς την προσωρινή μνήμη. Στη συνέχεια έγραψα μερικά σενάρια: Αυτόματη αντιγραφή sw.js, manifest.json και offline.html στο έργο σας. Εισάγετε μια ενέργεια διακομιστή που ονομάζεται revalidatePWA που μπορείτε να χρησιμοποιήσετε οπουδήποτε (διόδους API, ενέργειες διακομιστή, εξαρτήματα διακομιστή - πάρτε την επιλογή σας). Για την πλήρη υποστήριξη του App Router και SSR / Edge, έχω τυλίξει τα πάντα σε μια λειτουργία υψηλότερης τάξης: Μια εισαγωγή, μία κλήση – ολοκληρώθηκε. withPWA Έχω επίσης δημιουργήσει σε καρτέλα συγχρονισμού. επειδή οι χρήστες ανοίξτε την εφαρμογή σας σε 3 καρτέλες και περιμένετε να ενημερωθούν μαγικά σε συγχρονισμό. + το των γεγονότων. Θα localStorage storage Το αποτέλεσμα; Ένα πακέτο που απλά λειτουργεί. Δεν διαμορφώνετε μαύρη μαγεία. Δεν ξαναγράφετε τα βασικά μέρη της εφαρμογής σας. Τι παίρνεις με Επόμενο Πακέτο Επόμενο Πακέτο Μόλις εγκατασταθεί, μπορείτε να πάρετε: Εγγραφή υπαλλήλου υπηρεσιών έξω από το κουτί - χωρίς λέβητα. Offline Fallback με ένα προσαρμόσιμο offline.html. Αυτοματοποιημένα αρχεία που μπορείτε να προσαρμόσετε (manifest, SW, κ.λπ.). API ελέγχου προσωρινής αποθήκευσης - καθαρή, ενημέρωση, απενεργοποίηση, όλα προγραμματικά. Συγχρονισμός μεταξύ καρτών – δεν υπάρχει σταθερό περιεχόμενο στις ρυθμίσεις πολλαπλών καρτών. Πίνακας ανάπτυξης για κατάσταση PWA σε πραγματικό χρόνο κατά τη διάρκεια της τοπικής ανάπτυξης. Υποστήριξη επαναβεβαίωσης από την πλευρά του διακομιστή μέσω ενεργειών διακομιστή, διαδρομών API ή εξωτερικών ενοποιήσεων webhook. Μπορείτε να βρείτε το πακέτο εδώ: https://github.com/dev-family/next-pwa-pack Τι συμβαίνει όταν το εγκαταστήσετε Το σενάριο εγκατάστασης αντιγράφει αυτόματα το boilerplate PWA σε : /public sw.js – ο υπάλληλος υπηρεσιών σας με λογική προσωρινής αποθήκευσης. offline.html – Fallback page για offline λειτουργία. manifest.json – ρυθμίστε το για να ταιριάζει στην εφαρμογή σας. Τα υπάρχοντα αρχεία δεν θα υπεργραφούν - σέβεται την εγκατάστασή σας. Εάν θέλετε να ενεργοποιήσετε το αντίγραφο με μη αυτόματο τρόπο: node node_modules/next-pwa-pack/scripts/copy-pwa-files.mjs # or npx next-pwa-pack/scripts/copy-pwa-files.mjs Η δράση του server Επίσης, προστίθεται στο ή Ανάλογα με τη δομή του φακέλου σας: 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(); } Εάν αυτό το αρχείο δεν εμφανίζεται, μπορείτε να εκτελέσετε: node node_modules/next-pwa-pack/scripts/copy-pwa-server-actions.mjs Διαμόρφωση της manifest.json Ετικέτες.json Μετά την εγκατάσταση, μην ξεχάσετε να προσαρμόσετε : /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" } ] } Βάλτε τις εικόνες σας σε ή να βγάλουν τα ίχνη τους από πάνω.Δεν είναι κακό. public/icons/ Γρήγορη εκκίνηση: Wire It Up Βάλτε το layout σας στο Και η μαγεία χτυπάει: PWAProvider import { PWAProvider } from "next-pwa-pack"; export default function layout({ children }) { return <PWAProvider>{children}</PWAProvider>; } Εάν θέλετε η επαναβεβαίωση να λειτουργεί από την πλευρά του διακομιστή, θα πρέπει επίσης να ενημερώσετε το μεσαίο λογισμικό σας: // /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: originalMiddleware: το βασικό σας middleware (π.χ. για i18n ή auth). revalidationSecret: μυστικό token για να κλειδώσετε την επικύρωση cache. sseEndpoint: διαδρομή ροής SSE (αλλαγή εάν συγκρούεται). webhookPath: endpoint to hit για την ενεργοποίηση ανανέωσης cache (χρησιμοποιείται από revalidatePWA). Μέσα στο ΠΡΟΜΗΘΕΥΤΗΣ ΠΡΟΜΗΘΕΥΤΗΣ Η Συμπλέξτε μια δέσμη αντικειμένων κάτω από το καπάκι - και μπορείτε επίσης να επιλέξετε τα εξαρτήματα κερασιού: PWAProvider RegisterSW Αυτόματη εγγραφή του υπαλλήλου της υπηρεσίας ( Αντιμετωπίζει τα λάθη χαριτωμένα.Μπορείτε να παρακάμψετε το μονοπάτι αν χρειαστεί: /sw.js <PWAProvider swPath="/custom/sw.js">{children}</PWAProvider> CacheCurrentPage Ανιχνεύει την πλοήγηση (συμπεριλαμβανομένων των μεταβάσεων στυλ SPA), αποθηκεύει την HTML της τρέχουσας σελίδας. SWRevalidateListener Παρατηρεί εκδηλώσεις localStorage και ενεργοποιεί την ανανέωση προσωρινής μνήμης σε διάφορες καρτέλες. SSERevalidateListener Λειτουργεί ως server-sent events από το Όταν το backend σας λέει "επαναβεβαιώστε αυτές τις διευθύνσεις URL", αυτός ο ακροατής εξασφαλίζει ότι οι πελάτες το κάνουν. sseEndpoint DevPWAStatus Dev-only panel μπορείτε να ενεργοποιήσετε ως εξής: <PWAProvider devMode>{children}</PWAProvider> Οι παραστάσεις: Διαδικτυακή / Offline κατάσταση Κρυφή εκδοχή Ενημέρωση διαθεσιμότητας Εργαλεία με ένα κλικ: καθαρή προσωρινή μνήμη, unregister SW, ανανέωση, απενεργοποίηση / ενεργοποίηση της προσωρινής μνήμης Τι κάνει στην πραγματικότητα ο εργαζόμενος Ο πυρήνας Χειροπέδες : sw.js Το HTML Caching Σελίδες προσωρινής αποθήκευσης με TTL (κατά προεπιλογή: 10 min — tweakable in sw.js) Αυτόματη επικύρωση όταν λήξει το TTL Απενεργοποίηση αν λείπει η HTML Στατικά περιουσιακά στοιχεία JS, CSS, εικόνες είναι προσωρινά αποθηκευμένες για πάντα Μόνο τα caches λαμβάνουν αιτήματα Υποστήριξη μηνυμάτων Υποστηρίζει αυτές τις ενέργειες από τον πελάτη: CACHE_CURRENT_ΧΤΜΛ Αξιολόγηση_URL DISABLE_CACHE / ENABLE_CACHE Οδηγίες Πλοίο - Περιμένοντας ΚΛΕΙΔΙΑΣΜΟΣ - ΚΛΕΙΔΙΑΣΜΟΣ Offline μόδα Σερβίρει offline.html εάν αποτύχουν τόσο το δίκτυο όσο και η προσωρινή μνήμη Προσπαθεί να αναζωογονήσει όταν επιστρέφει online Χρησιμοποιώντας Στο Middleware Σπυράκια Σπυράκια Εδώ είναι που Φέρνει την επικύρωση cache στο SSR και το Edge Middleware - με υποστήριξη SSE και όλα αυτά. next-pwa-pack export default withPWA(originalMiddleware, { revalidationSecret: process.env.REVALIDATION_SECRET!, sseEndpoint: "/api/pwa/cache-events", webhookPath: "/api/pwa/revalidate", }); Params: αρχικόMiddleware: η υπάρχουσα λογική middleware σας (auth, i18n, κ.λπ.) revalidationSecret: έτσι ώστε κανένας άλλος να μην μπορεί να κλέψει την προσωρινή μνήμη σας sseEndpoint: υπερβείτε εάν κάτι άλλο χρησιμοποιεί αυτή τη διαδρομή webhookPath: χρησιμοποιείται από το διακομιστή ή εξωτερικά συστήματα για την επαναβεβαίωση συγκεκριμένων διευθύνσεων URL Πραγματικές περιπτώσεις χρήσης Ενημέρωση Cache μετά από αλλαγές δεδομένων import { updateSWCache } from "next-pwa-pack"; // After creating a blog post: const handleCreatePost = async (data) => { await createPost(data); updateSWCache(["/blog", "/dashboard"]); }; Ενημέρωση του cache από τον server import { revalidatePWA } from "../actions"; await createPost(data); await revalidatePWA(["/my-page"]); Καθαρισμός Cache στο Logout import { clearAllCache } from "next-pwa-pack"; const handleLogout = async () => { await logout(); await clearAllCache(); router.push("/login"); }; Όλες οι ενέργειες Cache του πελάτη 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 Route για εξωτερικούς ενεργοποιητές cache Εάν θέλετε να ενεργοποιήσετε ανανεώσεις cache εξωτερικά (π.χ. από έναν πίνακα διαχείρισης), εδώ είναι μια διαδρομή API που μπορείτε να χρησιμοποιήσετε: // 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 }); } } Χτυπήστε το με: POST https://your-app.com/api/webhook/revalidate { "tags": ["faq"], "secret": "1234567890", "urls": ["/ru/question-answer"] } Debugging και DevTools Εδώ είναι τι μπορείτε να ελέγξετε κατά την ανακύκλωση: Μεταβείτε στο DevTools → Application → Service Workers. Επιβεβαιώστε ότι ο εργαζόμενος είναι εγγεγραμμένος. Ελέγξτε την προσωρινή αποθήκευση → html-cache-v2 για να δείτε αν οι σελίδες είναι προσωρινά αποθηκευμένες. Προσομοίωση εκτός σύνδεσης στο δίκτυο → εκτός σύνδεσης και επαναφόρτωση. θα πρέπει να δείτε το offline.html. Console logs from the service worker help too: [PWA] Service Worker registered [SW] Cached: /about [SW] Revalidated and updated cache for: /blog Γκότα & Σημειώσεις Μερικά πράγματα που πρέπει να γνωρίζετε πριν από το πλοίο: Ασφάλεια Το PWA απαιτεί HTTPS στην παραγωγή. Μόνο τα αιτήματα γίνονται αποθηκευμένα. Μην κρύβετε ευαίσθητα δεδομένα. Επίδοση Το πακέτο δεν αγγίζει τη βάση απόδοσης της εφαρμογής σας. Βελτιώνει σημαντικά τα επαναλαμβανόμενα φορτία. Συμφωνία Το TTL έχει οριστεί σε sw.js (προεπιλογή: 10 λεπτά). Μπορείτε να αποκλείσετε τις διευθύνσεις URL από την προσωρινή αποθήκευση μέσω του CACHE_EXCLUDE. Το manifest.json πρέπει να είναι προσαρμοσμένο στην εφαρμογή σας. Η ενέργεια revalidatePWA μπορεί να επεξεργαστείται – προσαρμόστε την ανάλογα με τις ανάγκες. withPWA και PWAProvider και οι δύο αποδέχονται επιλογές: export default function PWAProvider({ children, swPath, devMode = false, serverRevalidation = { enabled: true, sseEndpoint: "/api/pwa/cache-events" }, }: PWAProviderProps) { ΤΙ ΕΙΝΑΙ ΕΠΟΜΕΝΟ Είναι γραμμένο για Θα πρέπει να λειτουργεί σε Επίσης - απλά δεν δοκιμάστηκε εκτενώς. next-pwa-pack Next.js 15 Next.js 13 App Router Τα προγραμματισμένα χαρακτηριστικά: TTL διαμόρφωση μέσω επιλογών (χωρίς επεξεργασία sw.js) Πιέστε ειδοποιήσεις Έλεγχος Cache με βάση τα πρότυπα Μετρήσεις απόδοσης για την αποτελεσματικότητα της cache Αυτό είναι. Εάν είστε κουρασμένοι από τη χειροκίνητη διαμάχη των εργαζομένων της υπηρεσίας, δώστε Θα πάτε από το μηδέν στην πλήρη υποστήριξη PWA σε ένα διάλειμμα καφέ. next-pwa-pack Ερωτήσεις, σφάλματα ή ανατροφοδότηση; Ανοίξτε ένα ζήτημα ή χτυπήστε μας. github.com/dev-οικογένεια/next-pwa-pack