javascript - example - Expirar el caché en require.js data-main
requirejs github (2)
Estoy usando require.js y r.js para empaquetar mis módulos AMD. Estoy usando jquery & requirejs a través de la siguiente sintaxis:
<script data-main="/js/client" src="/js/external/require-jquery.js"></script>
Todo esto funciona muy bien en el empaquetado previo y posterior, pero me topa con muchos problemas donde Chrome y Safari móvil se aferran a la versión en caché de client.js. Me gustaría agregar un cachebuster a client.js, pero parece que no puedo entender cómo hacerlo usando la sintaxis anterior.
Intenté algunas variaciones de:
<script data-main="js/client.js?b=busted" src="/js/external/require-jquery.js"></script>
pero ahora requiere intentos para obtener client.js de /
, not /js
, entonces es 404s.
También intenté agregar
urlArgs : "bust="+new Date().getTime()
require.config
, pero parece no tener ningún efecto.
También intenté agregar el mismo valor a app.build.js
, pero cuando está allí, r.js ya no concatena mis archivos js, simplemente los reutiliza.
¿Cuál es la sintaxis adecuada para reventar un caché de script principal de datos require.js?
Aquí está mi solución (para emergencias):
- Busque el siguiente código en require.js:
Versión de desarrollo
//Join the path parts together, then figure out if baseUrl is needed.
url = syms.join(''/'');
url += (ext || (/^data/:|^blob/:|/?/.test(url) || skipExt ? '''' : ''.js''));
url = (url.charAt(0) === ''/'' || url.match(/^[/w/+/./-]+:/) ? '''' : config.baseUrl) + url;
O
Versión de producción
e).join("/"),h=m(d,h)){H(h)&&(h=h[0]);a.splice(0,e,h);break}d=a.join("/");d+=b||(/^data/:|/?/.test(d)||c?"":".js");
y agregue
?v=x.0
después de.js
url += (ext || (/^data/:|^blob/:|/?/.test(url) || skipExt ? '''' : ''.js?v=1.0''));
O
(/^data/:|/?/.test(d)||c?"":".js?v=1.0");
¿Cómo está definiendo su require.config? Creo que para que tenga efecto antes de importar require.js, debe codificarlo así:
<script type="text/javascript">
var require = {
baseUrl: "/scripts/",
waitSeconds: 15,
urlArgs : "bust="+new Date().getTime()
};
</script>
<script data-main="app/main" src="/scripts/require.js"></script>
Específicamente, debe construirse un objeto llamado ''require'' antes de importar require.js.
ACTUALIZAR
Como señala Jesse en los comentarios a continuación, hay algunas mejoras que debe aplicar a su objeto require {} para uso en producción. El ejemplo anterior está copiado de la documentación de RequireJS y se ha modificado lo menos posible para responder esta pregunta.
Aquí hay algunas cosas a considerar para el uso de producción:
- En lugar de utilizar la fecha-hora actual como su variable de prevención de caché, debe usar un número de compilación de su entorno de desarrollo. Esto permite a sus clientes almacenar en caché el Javascript entre lanzamientos, pero hará que actualicen su caché cada vez que realice una actualización de software.
- Jesse también usa la capacidad de require {} para especificar dependencias en lugar de usar el atributo principal de datos del script. No sé si eso es estrictamente mejor , pero creo que es más limpio.
- Ajuste los waitSeconds según sus necesidades. Utilicé el valor de ejemplo de la documentación RequireJS, pero debe ajustar el valor u omitirlo, en función de sus necesidades.
Entonces, si aplica estas técnicas, su código podría verse así:
<script type="text/javascript">
var require = {
baseUrl: "/scripts/",
waitSeconds: 15,
urlArgs : "bust="+{{buildNumber}},
deps : [''app/main'']
};
</script>
<script src="/scripts/require.js?bust={{buildNumber}}"></script>
Tenga en cuenta que, en este caso, {{buildNumber}} es un valor proporcionado por el servidor.
ACTUALIZACIÓN 2
La solución de bus caché urlArgs tiene problemas. Lamentablemente, no puede controlar todos los servidores proxy que puedan estar entre usted y el navegador web de su usuario. Desafortunadamente, algunos de estos servidores proxy pueden configurarse para ignorar los parámetros de URL al almacenar en caché los archivos. Si esto sucede, la versión incorrecta de su archivo JS será entregada a su usuario.
Yo recomendaría usar un buildNumber
en su solicitud de archivo JavaScript, como buildNumber.myModule.js
(prefix) o myModule.buildNumber.js (postfix). Puede usar el estilo de prefijo modificando la baseUrl:
baseUrl: "/scripts/buildNumber",
Tenga en cuenta la falta de un ''/'' al final de la baseUrl.
Tendrá que usar una versión modificada de require.js para usar la solución postfix. Puede leer más sobre esto aquí: https://.com/a/21619359/1017787
Obviamente, en cualquier caso, querrá utilizar alguna solución para reemplazar buildNumber
con algún tipo de número de versión que cambie con cada versión.