VueJS / construcciones de producción de caché del navegador

Tengo una aplicación VueJS. Cada vez que ejecuto npm run build crea un nuevo conjunto de archivos dist/* , sin embargo, cuando los cargo en el servidor (después de eliminar la comstackción anterior), y abro la página en el navegador, se carga la comstackción antigua (desde el caché i asumir). Cuando actualizo la página, carga el nuevo código sin ningún problema.

Este es mi index.html:

              

¿Hay alguna forma de forzarlo a cargar código nuevo cada vez o (idealmente) verificar si los archivos antiguos han desaparecido del servidor y luego actualizar el navegador?

Luchamos con este mismo problema y descubrimos que los navegadores de algunas personas ni siquiera sacaban la versión más reciente a menos que se actualizaran manualmente. Tuvimos problemas con el almacenamiento en caché en varias capas, incluida la CDN donde alojábamos archivos.

También tuvimos problemas para mantener las versiones y poder volver a implementar rápidamente una versión anterior si algo sale mal.

Nuestra solución (usando un proyecto basado en vue-cli Webpack):

1) Construimos la distribución para tener una carpeta específica de la versión en lugar de ‘estática’. Esto también nos ayuda a rastrear las construcciones y “deshacer” una implementación si es necesario. Para cambiar el directorio ‘estático’, cambie ‘assetSubDirectory’ en ‘build’ en index.js y cambie ‘assetPublicPath’ a su ruta de acceso de CDN.

2) Usamos Webpack Assets Manifest para construir un archivo manifest.json que apunta a todos los activos. Nuestro manifiesto incluye un hash de todos los archivos, ya que es una aplicación de alta seguridad.

3) Subimos la carpeta versionada (que contiene los archivos js y css) a nuestro CDN.

4) (Opcional) Alojamos un archivo index.html dynamic en el servidor backend. Los enlaces a la hoja de estilo y los scripts se completan mediante el servidor backend utilizando un sistema de plantilla extraído de los datos en el archivo manifest.json (consulte el número 5). Esto es opcional, ya que podría usar la opción forzar recarga como se muestra en el comentario a continuación, que no es una gran experiencia pero funciona.

5) Para publicar una nueva versión, publicamos el archivo manifest.json en el servidor backend. Hacemos esto a través de un punto final GraphQL, pero usted podría poner manualmente el archivo json en algún lugar. Lo almacenamos en la base de datos y lo usamos para llenar el index.html y también lo usamos para verificar los archivos usando el hash del archivo (para validar nuestro CDN no fue pirateado).

Resultado: actualizaciones inmediatas y una capacidad sencilla para rastrear y cambiar sus versiones. Descubrimos que inmediatamente se lanzará la nueva versión en casi todos los navegadores de los usuarios.

Otra ventaja adicional: estamos creando una aplicación que requiere alta seguridad y alojar el index.html en nuestro backend (ya asegurado) nos permitió pasar nuestras auditorías de seguridad más fácilmente.


Editar 2/17/19

Encontramos que las redes corporativas estaban realizando el almacenamiento en caché de proxy, a pesar de los encabezados sin caché. IE 11 también parece ignorar los encabezados de caché. Por lo tanto, algunos usuarios no estaban obteniendo las versiones más actualizadas.

Tenemos una version.json que se incrementa / define en el momento de la comstackción. El número de versión está incluido en manifest.json. El paquete de comstackción se carga automáticamente en S3. Luego pasamos el archivo manifest.json al backend (hacemos esto en una página de entrada en el área de administración). A continuación, establecemos la versión “activa” en esa interfaz de usuario. Esto nos permite cambiar / revertir fácilmente las versiones.

El backend pone la “versión actual” como un encabezado de respuesta en todas las solicitudes. Si currentVersion! == version (como se define en version.json), entonces le pedimos al usuario que haga clic para actualizar su navegador (en lugar de forzarlo).

Basándose en esta respuesta integral en los encabezados de la memoria caché , su mejor apuesta será resolver esto en el lado del servidor si tiene el control, ya que cualquier cosa en las tags se anulará por los encabezados establecidos por el servidor.

Los comentarios sobre la pregunta indican que está sirviendo esta aplicación con nginx. Usando la respuesta vinculada anterior, pude establecer los encabezados Cache-Control , Expires y Pragma para cualquier solicitud de archivos que terminen en .html esta manera en mi configuración de nginx:

 server { ...other config location ~* \.html?$ { expires -1; add_header Pragma "no-cache"; add_header Cache-Control "no-store, must-revalidate"; } } 

Esto obliga con éxito al navegador a solicitar el último index.html en cada recarga de la página, pero aún usa los recursos en caché (js / css / fonts / images) a menos que haya nuevas referencias en la última respuesta html.