O RequireJS parece fazer algo internamente que armazena em cache os arquivos javascript necessários. Se eu fizer uma alteração em um dos arquivos necessários, tenho que renomear o arquivo para que as alterações sejam aplicadas.
O truque comum de acrescentar um número de versão como um parâmetro de string de consulta ao final do nome do arquivo não funciona com requirejs <script src="jsfile.js?v2"></script>
O que estou procurando é uma maneira de impedir esse cache interno dos scripts necessários do RequireJS sem precisar renomear meus arquivos de script toda vez que eles forem atualizados.
Solução multiplataforma:
Agora, estou usando o urlArgs: "bust=" + (new Date()).getTime()
bloqueio automático de cache durante o desenvolvimento e urlArgs: "bust=v2"
a produção, onde incremento o número da versão codificada depois de lançar um script necessário atualizado.
Nota:
O @Dustin Getz mencionou em uma resposta recente que as Ferramentas para Desenvolvedor do Chrome eliminarão pontos de interrupção durante a depuração quando os arquivos Javascript forem atualizados continuamente dessa maneira. Uma solução alternativa é escrever um debugger;
código para acionar um ponto de interrupção na maioria dos depuradores Javascript.
Soluções específicas de servidor:
Para soluções específicas que podem funcionar melhor no seu ambiente de servidor, como Node ou Apache, consulte algumas das respostas abaixo.
fonte
Respostas:
O RequireJS pode ser configurado para anexar um valor a cada um dos URLs de script para impedir o cache.
Na documentação do RequireJS ( http://requirejs.org/docs/api.html#config ):
Exemplo, anexando "v2" a todos os scripts:
Para fins de desenvolvimento, você pode forçar o RequireJS a ignorar o cache anexando um carimbo de data / hora:
fonte
urlArgs: "bust=" + (new Date()).getTime()
bloqueio automático de cache durante o desenvolvimento eurlArgs: "bust=v2"
a produção, onde incremento o número da versão codificada depois de lançar um script necessário atualizado.urlArgs: "bust=" + (+new Date)
urlArgs
.Não use urlArgs para isso!
Exigir que as cargas de script respeitem os cabeçalhos de cache http. (Os scripts são carregados com uma inserção dinâmica
<script>
, o que significa que a solicitação se parece com qualquer ativo antigo sendo carregado.)Sirva seus recursos javascript com os cabeçalhos HTTP adequados para desativar o cache durante o desenvolvimento.
O uso de urlArgs do require significa que quaisquer pontos de interrupção definidos por você não serão preservados entre as atualizações; você acaba precisando colocar
debugger
instruções em todo lugar no seu código. Ruim. Eu usourlArgs
para ativos de bloqueio de cache durante as atualizações de produção com o git sha; então, posso definir meus recursos para que sejam armazenados em cache para sempre e garantir que eles nunca terão recursos obsoletos.No desenvolvimento, eu simulei todas as solicitações de ajax com uma configuração complexa de mockjax e posso servir meu aplicativo no modo somente javascript com um servidor http python de 10 linhas com todo o cache desativado . Isso foi ampliado para um aplicativo "corporativo" bastante grande, com centenas de pontos de extremidade de serviço da web repousantes. Temos até um designer contratado que pode trabalhar com nossa base de código de produção real sem dar a ele acesso ao nosso código de back-end.
fonte
debugger;
em seu código sempre que quiser que um ponto de interrupção persista.A solução urlArgs tem problemas. Infelizmente, você não pode controlar todos os servidores proxy que possam estar entre você e o navegador da web do usuário. Infelizmente, alguns desses servidores proxy podem ser configurados para ignorar os parâmetros de URL ao armazenar arquivos em cache. Se isso acontecer, a versão errada do seu arquivo JS será entregue ao seu usuário.
Finalmente desisti e implementei minha própria correção diretamente no require.js. Se você estiver disposto a modificar sua versão da biblioteca requirejs, esta solução poderá funcionar para você.
Você pode ver o patch aqui:
https://github.com/jbcpollak/requirejs/commit/589ee0cdfe6f719cd761eee631ce68eee09a5a67
Uma vez adicionado, você pode fazer algo assim em sua configuração de requisição:
Use o sistema de construção ou o ambiente do servidor para substituir
buildNumber
por um ID de revisão / versão do software / cor favorita.Usando exigem assim:
Causará exigir para solicitar este arquivo:
Em nosso ambiente de servidor, usamos regras de reescrita de URL para remover o buildNumber e servir o arquivo JS correto. Dessa forma, não precisamos nos preocupar em renomear todos os nossos arquivos JS.
O patch ignorará qualquer script que especifique um protocolo e não afetará nenhum arquivo não-JS.
Isso funciona bem para o meu ambiente, mas eu sei que alguns usuários preferem um prefixo ao invés de um sufixo. Deve ser fácil modificar meu commit para atender às suas necessidades.
Atualizar:
Na discussão da solicitação de recebimento, o autor do requirejs sugere que isso pode funcionar como uma solução para prefixar o número da revisão:
Eu não tentei isso, mas a implicação é que isso solicitaria o seguinte URL:
O que pode funcionar muito bem para muitas pessoas que podem usar um prefixo.
Aqui estão algumas perguntas duplicadas possíveis:
RequireJS e cache de proxy
require.js - Como posso definir uma versão nos módulos necessários como parte da URL?
fonte
/scripts/myLib/v1.1/
. Tentei adicionar postfix (ou prefixo) aos meus nomes de arquivos, provavelmente porque é isso que o jquery faz, mas depois de um tempo eu fiquei preguiçoso e comecei a incrementar um número de versão na pasta pai. Eu acho que facilitou a manutenção para mim em um site grande, mas agora você me preocupa com pesadelos de reescrita 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>
Inspirados no cache Expirar em require.js data-main , atualizamos nosso script de implantação com a seguinte tarefa ant:
Como é o início do main.js:
fonte
Em produção
urlArgs
pode causar problemas!O principal autor do requirejs prefere não usar
urlArgs
:[Styling mine.]
Eu sigo este conselho.
Em desenvolvimento
Prefiro usar um servidor que armazene em cache de maneira inteligente os arquivos que podem mudar com freqüência: um servidor que emite
Last-Modified
e respondeIf-Modified-Since
com 304 quando apropriado. Mesmo um servidor baseado no conjunto expresso do Node para servir arquivos estáticos faz isso imediatamente. Ele não requer nada no meu navegador e não atrapalha os pontos de interrupção.fonte
Peguei esse trecho do AskApache e coloquei em um arquivo .conf separado do meu servidor web Apache local (no meu caso /etc/apache2/others/preventcaching.conf):
Para o desenvolvimento, isso funciona bem, sem a necessidade de alterar o código. Quanto à produção, eu poderia usar a abordagem do @ dvtoever.
fonte
Correção rápida para desenvolvimento
Para o desenvolvimento, você pode simplesmente desativar o cache nas Ferramentas de Desenvolvimento do Chrome ( Desativando o cache do Chrome para desenvolvimento de sites) ). A desativação do cache ocorre apenas se a caixa de diálogo dev tools estiver aberta; portanto, você não precisa se preocupar em alternar essa opção sempre que fizer uma navegação regular.
Nota: Usar ' urlArgs ' é a solução adequada na produção, para que os usuários obtenham o código mais recente. Mas isso dificulta a depuração porque o chrome invalida pontos de interrupção a cada atualização (porque é um arquivo 'novo' sendo veiculado toda vez).
fonte
Não recomendo usar ' urlArgs ' para armazenamento em cache com RequireJS. Como isso não resolve o problema completamente. A atualização de uma versão no resultará no download de todos os recursos, mesmo que você tenha alterado apenas um único recurso.
Para lidar com esse problema, recomendo o uso de módulos Grunt como 'filerev' para criar a revisão no. Além disso, escrevi uma tarefa personalizada no Gruntfile para atualizar a revisão sempre que necessário.
Se necessário, posso compartilhar o trecho de código para esta tarefa.
fonte
É assim que eu faço no Django / Flask (pode ser facilmente adaptado a outros idiomas / sistemas VCS):
No seu
config.py
(eu uso isso em python3, então você pode precisar ajustar a codificação em python2)Em seguida, no seu modelo:
git rev-parse HEAD
uma vez quando o aplicativo é iniciado e o armazena noconfig
objetofonte
Solução dinâmica (sem urlArgs)
Existe uma solução simples para esse problema, para que você possa carregar um número de revisão exclusivo para cada módulo.
Você pode salvar a função requirejs.load original, substituí-la por sua própria função e analisar seu URL modificado para o requirejs.load original novamente:
Em nosso processo de construção, usei "gulp-rev" para criar um arquivo de manifesto com todas as revisões de todos os módulos que estão sendo usados. Versão simplificada da minha tarefa gulp:
isso gerará um módulo AMD com números de revisão para moduleNames, que está incluído como 'oRevision' no main.js., onde você substitui a função requirejs.load como mostrado anteriormente.
fonte
Isso é uma adição à resposta aceita por @phil mccull.
Eu uso o método dele, mas também automatizo o processo criando um modelo T4 para ser executado antes da compilação.
Comandos de pré-compilação:
Modelo T4:
Arquivo gerado:
Armazene na variável antes que o require.config.js seja carregado:
Referência em require.config.js:
fonte
No meu caso, eu queria carregar o mesmo formulário cada vez que clicar, não queria que as alterações feitas no arquivo permanecessem. Pode não ser relevante para esta postagem exatamente, mas pode ser uma solução em potencial no lado do cliente sem definir a configuração para require. Em vez de enviar o conteúdo diretamente, você pode fazer uma cópia do arquivo necessário e manter o arquivo real intacto.
fonte