RequireJS parece hacer algo internamente que almacena en caché los archivos javascript necesarios. Si hago un cambio en uno de los archivos requeridos, tengo que cambiar el nombre del archivo para que se apliquen los cambios.
El truco común de agregar un número de versión como un parámetro de cadena de consulta al final del nombre de archivo no funciona con requirejs <script src="jsfile.js?v2"></script>
Lo que estoy buscando es una forma de evitar este almacenamiento en caché interno de los scripts requeridos RequireJS sin tener que cambiar el nombre de mis archivos de script cada vez que se actualizan.
Solución multiplataforma:
Ahora estoy usando urlArgs: "bust=" + (new Date()).getTime()
para la eliminación automática de caché durante el desarrollo y urlArgs: "bust=v2"
para la producción donde incremente el número de versión codificada después de implementar un script requerido actualizado.
Nota:
@Dustin Getz mencionó en una respuesta reciente que las Herramientas para desarrolladores de Chrome eliminarán los puntos de interrupción durante la depuración cuando los archivos Javascript se actualicen continuamente de esta manera. Una solución alternativa es escribir debugger;
código para activar un punto de interrupción en la mayoría de los depuradores de Javascript.
Soluciones específicas del servidor:
Para obtener soluciones específicas que pueden funcionar mejor para el entorno de su servidor, como Node o Apache, consulte algunas de las respuestas a continuación.
fuente
Respuestas:
RequireJS se puede configurar para agregar un valor a cada una de las URL de script para el almacenamiento en caché.
De la documentación de RequireJS ( http://requirejs.org/docs/api.html#config ):
Ejemplo, agregando "v2" a todos los scripts:
Para fines de desarrollo, puede forzar a RequireJS a omitir el caché agregando una marca de tiempo:
fuente
urlArgs: "bust=" + (new Date()).getTime()
para la eliminación automática de caché durante el desarrollo yurlArgs: "bust=v2"
para la producción donde incremente el número de versión codificada después de implementar un script requerido actualizado.urlArgs: "bust=" + (+new Date)
urlArgs
.¡No use urlArgs para esto!
Requerir cargas de script respeta los encabezados de almacenamiento en caché http. (Las secuencias de comandos se cargan con una inserción dinámica
<script>
, lo que significa que la solicitud se parece a cualquier activo antiguo que se está cargando).Sirva sus activos de JavaScript con los encabezados HTTP adecuados para deshabilitar el almacenamiento en caché durante el desarrollo.
El uso de urlArgs de require significa que los puntos de interrupción que establezca no se conservarán en las actualizaciones; terminas necesitando poner
debugger
declaraciones en todas partes en tu código. Malo. Lo usourlArgs
para activos que destruyen la memoria caché durante las actualizaciones de producción con el git sha; entonces puedo configurar mis activos para que se almacenen en caché para siempre y garantizar que nunca tengan activos obsoletos.En el desarrollo, me burlo de todas las solicitudes de ajax con una configuración compleja de mockjax , luego puedo servir mi aplicación en modo solo javascript con un servidor http python de 10 líneas con todo el almacenamiento en caché desactivado . Esto se ha ampliado para mí a una aplicación "empresarial" bastante grande con cientos de puntos finales de servicio web relajantes. Incluso tenemos un diseñador contratado que puede trabajar con nuestra base de código de producción real sin darle acceso a nuestro código de back-end.
fuente
debugger;
en su código donde quiera que persista un punto de interrupción.La solución urlArgs tiene problemas. Lamentablemente, no puede controlar todos los servidores proxy que puedan estar entre usted y el navegador web de su usuario. Lamentablemente, algunos de estos servidores proxy se pueden configurar para ignorar los parámetros de URL al almacenar en caché los archivos. Si esto sucede, se le entregará a su usuario una versión incorrecta de su archivo JS.
Finalmente me di por vencido e implementé mi propia solución directamente en require.js. Si está dispuesto a modificar su versión de la biblioteca requirejs, esta solución podría funcionar para usted.
Puedes ver el parche aquí:
https://github.com/jbcpollak/requirejs/commit/589ee0cdfe6f719cd761eee631ce68eee09a5a67
Una vez agregado, puede hacer algo como esto en su configuración requerida:
Utilice su sistema de compilación o entorno de servidor para reemplazarlo
buildNumber
con una identificación de revisión / versión de software / color favorito.Usando requiere así:
Será necesario solicitar este archivo:
En nuestro entorno de servidor, usamos reglas de reescritura de URL para eliminar el número de compilación y servir el archivo JS correcto. De esta manera, no tenemos que preocuparnos por renombrar todos nuestros archivos JS.
El parche ignorará cualquier script que especifique un protocolo, y no afectará ningún archivo que no sea JS.
Esto funciona bien para mi entorno, pero me doy cuenta de que algunos usuarios preferirían un prefijo en lugar de un sufijo, debería ser fácil modificar mi confirmación para satisfacer sus necesidades.
Actualizar:
En la discusión de solicitud de extracción, el autor requirejs sugiere que esto podría funcionar como una solución para prefijar el número de revisión:
No he intentado esto, pero la implicación es que solicitaría la siguiente URL:
Lo que podría funcionar muy bien para muchas personas que pueden usar un prefijo.
Aquí hay algunas posibles preguntas duplicadas:
RequireJS y almacenamiento en caché de proxy
require.js - ¿Cómo puedo configurar una versión en los módulos requeridos como parte de la URL?
fuente
/scripts/myLib/v1.1/
. Intenté agregar postfix (o prefijo) a mis nombres de archivo, probablemente porque eso es lo que hace jquery, pero después de un tiempo [me volví flojo y] comencé a incrementar un número de versión en la carpeta principal. Creo que me ha facilitado el mantenimiento en un sitio web grande, pero ahora me tiene preocupado por las pesadillas de reescritura de URL.<script data-main="${pageContext.request.contextPath}/resources/scripts/main" src="${pageContext.request.contextPath}/resources/scripts/require.js"> <jsp:text/> </script> <script> require([ 'dev/module' ]); </script>
Inspirado por Expire cache en require.js data-main , actualizamos nuestro script de implementación con la siguiente tarea ant:
Donde se ve el comienzo de main.js:
fuente
En producción
urlArgs
puede causar problemas!El autor principal de requirejs prefiere no usar
urlArgs
:[Peinando el mío.]
Sigo este consejo.
En desarrollo
Prefiero utilizar un servidor que almacena en caché de manera inteligente los archivos que pueden cambiar con frecuencia: un servidor que emite
Last-Modified
y respondeIf-Modified-Since
con 304 cuando corresponde. Incluso un servidor basado en el conjunto rápido de Node para servir archivos estáticos lo hace de inmediato. No requiere hacer nada a mi navegador y no arruina los puntos de interrupción.fuente
Tomé este fragmento de AskApache y lo puse en un archivo .conf separado de mi servidor web Apache local (en mi caso /etc/apache2/others/preventcaching.conf):
Para el desarrollo, esto funciona bien sin necesidad de cambiar el código. En cuanto a la producción, podría usar el enfoque de @ dvtoever.
fuente
Solución rápida para el desarrollo
Para el desarrollo, puede deshabilitar el caché en Chrome Dev Tools ( deshabilitar el caché de Chrome para el desarrollo del sitio web ). La desactivación de la memoria caché ocurre solo si el cuadro de diálogo de herramientas de desarrollo está abierto, por lo que no debe preocuparse por alternar esta opción cada vez que navega regularmente.
Nota: El uso de ' urlArgs ' es la solución adecuada en producción para que los usuarios obtengan el código más reciente. Pero dificulta la depuración porque Chrome invalida los puntos de interrupción con cada actualización (porque es un archivo 'nuevo' que se sirve cada vez).
fuente
No recomiendo usar ' urlArgs ' para la explosión de caché con RequireJS. Como esto no resuelve el problema por completo. La actualización de una versión no dará como resultado la descarga de todos los recursos, aunque solo haya cambiado un solo recurso.
Para manejar este problema, recomiendo usar módulos Grunt como 'filerev' para crear la revisión no. Además de esto, he escrito una tarea personalizada en Gruntfile para actualizar la revisión no donde sea necesario.
Si es necesario, puedo compartir el fragmento de código para esta tarea.
fuente
Así es como lo hago en Django / Flask (se puede adaptar fácilmente a otros idiomas / sistemas VCS):
En su
config.py
(uso esto en python3, por lo que es posible que deba modificar la codificación en python2)Luego en su plantilla:
git rev-parse HEAD
una vez cuando se inicia la aplicación y la almacena en elconfig
objetofuente
Solución dinámica (sin urlArgs)
Hay una solución simple para este problema, para que pueda cargar un número de revisión único para cada módulo.
Puede guardar la función requirejs.load original, sobrescribirla con su propia función y analizar nuevamente su url modificada a la requirejs.load original:
En nuestro proceso de construcción usé "gulp-rev" para construir un archivo de manifiesto con todas las revisiones de todos los módulos que se están utilizando. Versión simplificada de mi tarea de trago:
esto generará un módulo AMD con números de revisión para moduleNames, que se incluye como 'oRevision' en main.js, donde sobrescribe la función requirejs.load como se mostró anteriormente.
fuente
Esto se suma a la respuesta aceptada de @phil mccull.
Utilizo su método, pero también automatizo el proceso creando una plantilla T4 para ejecutarla antes de la compilación.
Comandos precompilados:
Plantilla T4:
Archivo generado:
Almacenar en variable antes de cargar require.config.js:
Referencia en require.config.js:
fuente
En mi caso, quería cargar el mismo formulario cada vez que hago clic, no quería que se quedaran los cambios que hice en el archivo. Puede que no sea relevante para esta publicación exactamente, pero esta podría ser una solución potencial en el lado del cliente sin configurar config para require. En lugar de enviar el contenido directamente, puede hacer una copia del archivo requerido y mantener intacto el archivo real.
fuente