Home Ciencia y Tecnología Cómo hice Subsequent.js y PWA finalmente se llevan bien-con el siguiente paquete...

Cómo hice Subsequent.js y PWA finalmente se llevan bien-con el siguiente paquete de pwa

32
0

Me gusta crear herramientas que no solo funcionen, ellos salir de tu camino. Mi equipo ha estado en las trincheras de Subsequent.js el tiempo suficiente para saber exactamente qué duele. Una de las últimas cosas que preparé es next-pwa-pack -Un paquete de entrega que algue el soporte PWA completo en su aplicación Subsequent.js sin arrancarse el cabello.

La historia de fondo (también conocida como: por qué escribí esto)

Cada vez que un cliente mencionaba “soporte de PWA”, me preparaba.

Probé bibliotecas existentes. Demasiada magia. Toneladas de configuración. O simplemente completamente incompatible con Enrutador de aplicaciones – que, por cierto, hemos adoptado completamente. Quería:

  • Revalidación de caché del lado del servidor.
  • Integración del enrutador de aplicaciones.
  • Sincronización fácil entre pestañas.
  • Limpie la API para administrar el caché desde el backend.

En cambio, terminé escribiendo trabajadores de servicio a mano. Tuning Cache TTLS. Tratar con la lógica de actualización. Gestión de clientes rancios. Cachés de limpieza manualmente cada vez que enviamos.

Y ni siquiera me hagas comenzar con los usuarios que no veas actualizaciones hasta que se refrescan duro. Suficiente period suficiente.

Necesitaba algo muerto easy, predecible y probado en batalla. Entonces lo construí.

Edificio next-pwa-pack: Que entró

El primer paso period escribir un trabajador de servicio mínimo:

  • Caches html con ttl.
  • Maneja activos estáticos.
  • Funciona sin conexión, como debería un verdadero PWA.

Luego agregué un sistema de mensajería para que el cliente pudiera hablar con el trabajador del servicio, por ejemplo, para reventar un caché o deshabilitar el almacenamiento en caché por completo.

A continuación, escribí algunos guiones:

  • Copia automática sw.js, manifest.jsony offline.html en tu proyecto.
  • Inyectar una acción del servidor llamada revalidatePWA que puede usar en cualquier lugar (rutas API, acciones del servidor, componentes del servidor: elija su elección).

Para el enrutador de aplicaciones completo y el soporte de SSR/Edge, envolví todo en una función de orden superior: withPWA. Una importación, una llamada – HECHA.

También incorporé sincronización de pestañas. Porque usuarios voluntad Abra su aplicación en 3 pestañas y espere que se actualicen mágicamente sincronizar. Lo resolví a través de localStorage + + storage eventos.

El resultado? Un paquete que solo funciona. No config Magic negro. No reescribir partes centrales de su aplicación.

Lo que obtienes con next-pwa-pack

Una vez instalado, obtienes:

  • Registro de trabajadores de servicio Fuera de la caja, sin horario.
  • Alternativo fuera de línea con un personalizable offline.html.
  • Archivos automáticos Puedes ajustar (manifiesto, SW, and so on.).
  • API de management de caché – Borrar, actualizar, deshabilitar, todo programáticamente.
  • Sincronización entre pestañas -Sin contenido rancio en configuraciones de múltiples tabch.
  • Panel para el estado de PWA en tiempo actual durante el desarrollo native.
  • Revalidación del lado del servidor Soporte a través de acciones del servidor, rutas API o integraciones externas de webhook.

Puedes tomar el paquete aquí: 👉

¿Qué sucede cuando lo instala?

Instalar script auto-copias PWA Boilerplate en /public:

  • sw.js – Su trabajador de servicio con lógica de caché.
  • offline.html – Página de retroceso para el modo fuera de línea.
  • manifest.json – Ajustarlo para que se ajuste a su aplicación.

⚠️ Los archivos existentes no se sobrescribirán, respeta su configuración.

Si desea activar la copia manualmente:

node node_modules/next-pwa-pack/scripts/copy-pwa-files.mjs
# or
npx next-pwa-pack/scripts/copy-pwa-files.mjs

La acción del servidor revalidatePWA también se agrega a su app/actions.ts o src/app/actions.ts archivo dependiendo de la estructura de su carpeta:

"use server";
export async perform revalidatePWA(urls: string[]) {
 const baseUrl = course of.env.NEXT_PUBLIC_HOST || "
 const res = await fetch(`${baseUrl}/api/pwa/revalidate`, {
   methodology: "POST",
   headers: { "Content material-Sort": "software/json" },
   physique: JSON.stringify({
     urls,
     secret: course of.env.REVALIDATION_SECRET,
   }),
 });
 return res.json();
}

Si ese archivo no aparece, puede ejecutar:

node node_modules/next-pwa-pack/scripts/copy-pwa-server-actions.mjs

Configuración de su manifest.json

Después de la instalación, no olvide personalizar /public/manifest.json:

{
 "title": "My App",
 "short_name": "App",
 "description": "My wonderful PWA app",
 "start_url": "/",
 "show": "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"
   }
 ]
}

Deja tus íconos en public/icons/o ajustar los caminos de arriba. Nada lujoso.

Inicio rápido: cíquelo

Envuelva su diseño en el PWAProvidery la magia entra:

import { PWAProvider } from "next-pwa-pack";

export default perform structure({ youngsters }) {
  return {youngsters};
}

Si desea que la revalidación funcione desde el lado del servidor, también deberá actualizar su middleware:

// /middleware.ts
import { withPWA } from "next-pwa-pack/hoc/withPWA";

perform originalMiddleware(request) {
  // your logic right here
  return response;
}

export default withPWA(originalMiddleware, {
  revalidationSecret: course of.env.REVALIDATION_SECRET!,
  sseEndpoint: "/api/pwa/cache-events",
  webhookPath: "/api/pwa/revalidate",
});

export const config = en)/:path*", "/api/pwa/:path*"],
;

Las opciones hoc:

  • originalMiddleware: Tu middleware base (por ejemplo, para i18n o autent).
  • revalidationSecret: Token secreto para bloquear la revalidación de caché.
  • sseEndpoint: Ruta de transmisión SSE (cambie si entra en conflicto).
  • webhookPath: punto ultimate para presionar para activar la actualización de caché (utilizado por revalidatePWA).

Dentro del PWAProvider

El PWAProvider Embolsas un montón de cosas debajo del capó, y también puedes elegir componentes:

RegisterSW

Registra automáticamente el trabajador de servicio (/sw.js). Maneja errores con gracia. Puede anular la ruta si es necesario:

{youngsters}

CacheCurrentPage

Intercepts Navigation (incluidas las transiciones de estilo SPA), almacena en caché el HTML de la página precise.

SWRevalidateListener

Observa los eventos de la correa native y desencadena la actualización de la caché en las pestañas.

SSERevalidateListener

Escucha los eventos del servidor desde el sseEndpoint. Cuando su backend cube “Revaliden estas URL”, este oyente se asegura de que los clientes lo hagan.

DevPWAStatus

Panel solo de desarrollo que puede habilitar así:

{youngsters}

Mostrar:

  • Estado en línea/fuera de línea
  • Versión de caché
  • Actualizar disponibilidad
  • Herramientas de un solo clic: Despare caché, Unl Register SW, Actualice, Desactive/Habilite el caché

Lo que realmente hace el trabajador de servicio

El núcleo sw.js MANEJES:

Html en caché

  • Páginas almacenadas en almacenamiento en caché con TTL (predeterminado: 10 min – ajustable en sw.js)
  • Revalidados automáticos cuando expira TTL
  • Falta sin conexión si falta HTML

Activo estático

  • JS, CSS, las imágenes se almacenan en caché para siempre
  • Solo los cachés reciben solicitudes

Soporte de mensajería

Admite estas acciones del cliente:

  • CACHE_CURRENT_HTML
  • REVALIDATE_URL
  • DISABLE_CACHE / ENABLE_CACHE
  • SKIP_WAITING
  • CLEAR_STATIC_CACHE

Modo fuera de línea

  • Porción offline.html Si la pink y el caché fallan
  • Intenta refrescar cuando vuelve a estar en línea

Usando withPWA en el middleware

Aquí es donde next-pwa-pack Realmente gana su fortaleza. Trae la revalidación de caché a SSR y Middleware Edge, con soporte de SSE y todo.

export default withPWA(originalMiddleware, {
  revalidationSecret: course of.env.REVALIDATION_SECRET!,
  sseEndpoint: "/api/pwa/cache-events",
  webhookPath: "/api/pwa/revalidate",
});

Parámetros:

  • originalMiddleware: Su lógica de middleware existente (Auth, I18n, and so on.)
  • revalidationSecret: para que nadie más pueda pinchar tu caché
  • sseEndpoint: anular si algo más está usando esta ruta
  • webhookPath: utilizado por el servidor o los sistemas externos para revalidar las URL específicas

Casos de uso del mundo actual

Actualización de caché después de los cambios de datos

import { updateSWCache } from "next-pwa-pack";

// After making a weblog publish:
const handleCreatePost = async (knowledge) => {
  await createPost(knowledge);
  updateSWCache(["/blog", "/dashboard"]);
};

Actualización de caché desde el servidor

import { revalidatePWA } from "../actions";

await createPost(knowledge);
await revalidatePWA(["/my-page"]);

Borde de caché en el cierre de sesión

import { clearAllCache } from "next-pwa-pack";

const handleLogout = async () => {
  await logout();
  await clearAllCache();
  router.push("/login");
};

Todas las acciones de caché del cliente

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 { on-line, hasUpdate, swInstalled, replace } = usePWAStatus();

Ruta API para desencadenantes de caché externos

Si desea activar la caché, se actualiza externamente (por ejemplo, desde un panel de administración), aquí hay una ruta API que puede usar:

// app/api/webhook/revalidate/route.ts

import { NextRequest, NextResponse } from "subsequent/server";
import { revalidatePWA } from "@/app/actions";
import { revalidateTag } from "subsequent/cache";
import { FetchTags } from "@/app/api/endpoints/backend";

export async perform POST(request: NextRequest) {
  strive {
    const { tags, secret, urls } = await request.json();

    if (secret !== course of.env.REVALIDATION_SECRET) {
      return NextResponse.json({ error: "Unauthorized" }, { standing: 401 });
    }

    const validTags = Object.values(FetchTags);
    const invalidTags = tags?.filter((tag) => !validTags.contains(tag)) || [];

    if (invalidTags.size > 0) {
      return NextResponse.json(
        { error: `Invalid tags: ${invalidTags.be a part of(", ")}` },
        { standing: 400 }
      );
    }

    let profitable = 0;
    let failed = 0;

    if (tags?.size) {
      const tagResults = await Promise.allSettled(
        tags.map((tag) => revalidateTag(tag))
      );
      profitable = tagResults.filter((r) => r.standing === "fulfilled").size;
      failed = tagResults.filter((r) => r.standing === "rejected").size;
    }

    if (urls?.size) {
      await revalidatePWA(urls);
    }

    return NextResponse.json({
      success: true,
      message: "Cache revalidation accomplished",
      tags,
      urls,
      profitable,
      failed,
      timestamp: new Date().toISOString(),
    });
  } catch (error) {
    console.error("Webhook revalidation error:", error);
    return NextResponse.json({ error: "Inside server error" }, { standing: 500 });
  }
}

Golpearlo con:

POST 
{
  "tags": ["faq"],
  "secret": "1234567890",
  "urls": ["/ru/question-answer"]
}

Esto es lo que puede verificar al depurar:

  • Ir a DevTools → Aplicación → Trabajadores de servicios.
  • Confirmar que el trabajador está registrado.
  • Controlar Almacenamiento de caché → html-cache-v2 Para ver si las páginas se almacenan en caché.
  • Simular fuera de línea en Pink → fuera de línea y recargar. Deberías ver offline.html.
  • Los registros de la consola del trabajador del servicio también:
    • [PWA] Service Employee registered
    • [SW] Cached: /about
    • [SW] Revalidated and up to date cache for: /weblog

Gotchas y notas

Algunas cosas que debes saber antes de enviar:

Seguridad

  • PWA requiere HTTPS en producción.
  • Solo se almacenan en caché las solicitudes.
  • No almacenes en caché los datos confidenciales.

Actuación

  • El paquete no toca la línea de base de rendimiento de su aplicación.
  • Mejora significativamente las cargas repetidas.

Configuración

  • TTL está configurado en sw.js (predeterminado: 10 minutos).
  • Puede excluir a las URL de almacenamiento en caché a través de CACHE_EXCLUDE.
  • manifest.json necesita ser adaptado a su aplicación.
  • revalidatePWA La acción es editable: personalice según sea necesario.
  • withPWA y PWAProvider Ambos aceptan opciones:
export default perform PWAProvider({
  youngsters,
  swPath,
  devMode = false,
  serverRevalidation = {
    enabled: true,
    sseEndpoint: "/api/pwa/cache-events"
  },
}: PWAProviderProps) {

¿Qué sigue?

next-pwa-pack está escrito para Subsequent.js 15. Debería funcionar en Subsequent.js 13 APP Router Además, simplemente no se prueba ampliamente.

Características planificadas:

  • Configuración TTL a través de opciones (sin edición sw.js)
  • Notificaciones de empuje
  • Management de caché basado en patrones
  • Métricas de rendimiento para la eficiencia del caché

Eso es todo.

Si está cansado de que los trabajadores de servicio de disputas manualmente, entregue next-pwa-pack Un tiro. Pasará de cero a soporte PWA completo en un descanso para tomar un café.

Preguntas, errores o comentarios? Abra un problema o nos bateamos.

👉 github.com/dev-family/next-pwa-pack

fuente

LEAVE A REPLY

Please enter your comment!
Please enter your name here