Imagina la siguiente situación, bastante común por otro lado:

Estás desarrollando una aplicación JavaScript (generalmente de tipo Single Page Application), y utilizas la biblioteca require.js para realizar la modularización de la misma en lado cliente. Vas tocando tu código JavaScript y probándolo y depurándolo en diferentes navegadores. Eso implica lanzarlos con bastante frecuencia, albergando tu aplicación en un servidor web local para probar la aplicación. El problema surge porque el servidor web hace caché de los archivos estáticos (como son los .js) por lo que cada vez que cambias algo en un script, aunque refresques la página, no siempre vienen los cambios que has realizado.

Esto puede conducir a grandes frustraciones porque a veces cambias un carácter o una línea, crees que estás probando esa última versión, pero en realidad estás trabajando todavía con la versión anterior antes de los cambios. Hasta que te das cuenta pasan unos minutos preciosos que has perdido...

Obviamente puedes desactivar la caché del servidor y forzar siempre la descarga desde el cliente con ciertas cabeceras que se envían con todos los archivos. Pero esto es tedioso de configurar y además afectará seguramente a todos los archivos estáticos (o no, pero tendrás que tocar bastante configuración para lo contrario), no solo a los archivos JavaScript.

Si estás usando require.js para gestionar los diferentes módulos de la aplicación, existe un parámetro de configuración muy interesante que te permitirá solucionar de manera sencilla el problema de la caché.

Consiste simplemente en sacar partido al parámetro urlArgs de la configuración estándar de RequireJS, por ejemplo poniendo la línea destacada en tojo en el archivo principal de configuración (el resto de líneas son simplemente un ejemplo):

requirejs.config({
	baseUrl: 'js',
	urlArgs: "noCache=" + (new Date()).getTime(),
	paths: {
		text:'libs/text.min'
	}
});

De este modo lo que conseguimos es que requireJS añada automáticamente a todas las peticiones de archivos el parámetro indicado, en este caso "noCache" (pero podría ser cualquier otro nombre), al cual en este caso se le coloca como valor el número de segundos transcurridos desde el epoch de JavaScript (1/1/1970).

Es decir, cuando lancemos nuestra aplicación para depuración y pruebas veremos peticiones como estas:

requireJS-urlArgs

Fíjate en como las CSS y otros elementos estáticos no llevan el parámetro, pero el resto de peticiones a archivos .js realizadas por requireJS añaden automáticamente nuestro parámetro "noCache" con un valor numérico largo a continuación. Este valor cambia cada vez que lancemos la aplicación y obliga al navegador a realizar una petición nueva completa al servidor, descartando la caché local si la hubiese.

Nota: require.js y el módulo principal (main.js) obviamente no llevan ese parámetro porque hasta que cargan no se inicia el uso de AMD (Asynchronous Module Definition) para cargar los módulos.

Las ventajas de esta solución son:

  • La configuración depende solo de tu aplicación, y es un ajuste de lado cliente, sin que entre en juego el servidor en absoluto. Por ello te funcionará independientemente de qué servidor web utilices: Apache, Internet Information Server, NGinx...
  • Es tan fácil de configurar que puedes quitarlo para producción con solo comentar una línea de JavaScript. puedes incluirlo en tu proceso de build.
  • Afecta tan solo a los archivos JavaScript y plantillas (si utilizas la extensión !text de RequireJS) de tu aplicación, sin cambiar el comportamiento de caché de otro tipo de archivos estáticos como hojas de estilo o imágenes.

¡Espero que te resulte útil!

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor

Escrito por un humano, no por una IA