register pwa cli angular angular-cli angular-routing service-worker angular-service-worker

pwa - ¿Cómo manejar el enrutamiento en Angular 5+ Service Workers?



install angular service worker (1)

En versiones anteriores de la implementación de Angular Service Worker, una de las opciones de configuración era "routing" . Esto se puede ver en esta pregunta sin respuesta de SO , se hizo referencia en este problema de Angular CLI , y la mejor documentación restante parece ser la publicación del blog de Stephen Fluin (en el equipo de Angular), así como la charla de I / O de Alex Rickabaugh (de Google).

Con Angular 5, ServiceWorkerModule ha sido bien desarrollado y la mayoría de la configuración ahora puede manejarse usando el archivo ngsw-config.json . Sin embargo, ya no se menciona cómo manejar la redirección de rutas, en ninguna parte de la guía angular.io o en la documentation . Así que termino con el siguiente problema: cuando visité mi aplicación y me desconecté, todavía puedo acceder a la aplicación cuando la visito directamente: https://jackkoppa.github.io/cityaq-sw-issue . Sin embargo, al cargar, la aplicación redirige a la ruta de search , y la mayoría de los usuarios intentan cargar desde una URL como https://jackkoppa.github.io/cityaq-sw-issue/search?cities=Shanghai (por simplicidad, yo Solo estoy hablando de Chrome desktop & mobile, por ahora, y en Incognito cuando sea posible).

Cuando intenta visitar esa URL sin conexión, inmediatamente obtiene 504 - Tiempo de espera de la puerta de enlace. Esto sucede porque el trabajador del servicio solo ha guardado en caché el índice y no sabe que otras rutas deben redirigirse al índice para que pueda cargarse. Estoy seguro de que las iteraciones anteriores de la implementación del trabajador de servicio angular podrían haber manejado este escenario, mediante la configuración de redirecciones al índice para rutas determinadas. ¿Hay una manera de manejar este redireccionamiento en el actual, Angular 5+ ngsw-config.json , o en el archivo ngsw.json generado? De no ser así, ¿cómo debe manejarse una solución en un archivo JS de un trabajador de servicio separado?


TL; DR: He identificado al menos dos problemas que causan roturas en mi caso; puedes usar este script de compilación por ahora para probar mi corrección y ver cómo funciona la aplicación sin conexión here . Más pruebas y solicitudes de extracción necesarias.

Aunque no he podido encontrar una respuesta documentada, esto es lo que he podido encontrar hasta ahora, al ngsw-worker.js archivo ngsw-worker.js , así como al leer el historial de confirmación de @angular/service-worker .

El nuevo enfoque de ServiceWorkerModule para "enrutar" es tomar cualquier solicitud de "navegación" (es decir, una ruta no indexada en el mismo dominio) y volver a ejecutar el método handleFetch , pero ahora apuntando a la solicitud index.html ( source ). Esto debería funcionar bien, dado que un SPA debería poder redirigir a la URL una vez que haya recuperado sus archivos en caché para el índice.

Por lo tanto, los problemas que están causando que mi sitio anterior falle cuando no está conectado no deben estar directamente relacionados con el enrutamiento, y hasta ahora he encontrado 2. Corregir esto con una solución alternativa me ha permitido hacer que mi aplicación funcione principalmente como se esperaba. Con los pasos de repro en la pregunta original, here ahora está funcionando, mientras que he reproducido el sitio original y fallido en https://jackkoppa.github.io/cityaq-sw-issue .

Los problemas:

  1. Las versiones --base-href de una aplicación Angular, donde la --base-href se establece desde la CLI, enumeran las URL absolutas para sus recursos de trabajadores de servicio. Al comparar las solicitudes con estos recursos, ngsw-worker.js está esperando direcciones URL relativas

    • source
    • Estoy bastante seguro de que este problema debe resolverse y estaré trabajando en una solicitud de extracción para solucionarlo. Ocurre porque la baseHref se incluye en las URL de recursos cuando se genera ngsw.json ( source )
  2. De los 3 "estados" disponibles en los que puede estar ngsw-worker.js , según mi experiencia, EXISTING_CLIENTS_ONLY parece que la apuesta se ha establecido de forma incorrecta.

    • fuente 1 , fuente 2
    • Tengo menos confianza en este cambio, porque no he podido ver de manera consistente las causas de este estado. Sin embargo, si y cuando el trabajador del servicio entra en este estado, ngsw-worker.js ya no intentará recuperar los recursos almacenados en caché ( source ), y en mis pruebas en lo que parecen ser circunstancias "correctas", la aplicación aún entra en este estado incluso Cuando el único cambio es eliminar una conexión a internet.

Mientras armo un PR para el problema # 1, y espero cierta ayuda para entender el problema # 2, estoy usando una secuencia de comandos de compilación para modificar ngsw-worker.js después de que se genere. Advertencia: es feo y definitivamente modifica el comportamiento deseado "seguro" de establecer EXISTING_CLIENTS_ONLY . Sin embargo, para mi aplicación, permite un correcto desempeño fuera de línea cuando se ejecuta localmente ( http-server ) y se implementa en una URL activa (páginas de GitHub, en mi caso).

Para utilizar la solución alternativa: (Angular 5, probado con Angular 5.2.1)

  1. npm install replace-in-file --save-dev
  2. Incluya este script en su aplicación, por ejemplo, en build/fix-sw.js
  3. En su package.json :

"scripts": { ... "sw-build": "ng build --prod && node build/fix-sw", "sw-build-live": ng build --prod --base-href https://your-url.com/ && node build/fix-sw" ... }

  1. Para correr localmente

npm run sw-build cd dist http-server -p 8080

  1. Y para preparar una compilación para su URL en vivo, antes de enviarla a un servidor (por ejemplo, con angular-cli-ghpages )

npm run sw-build-live