Estou tentando usar o Grunt como uma ferramenta de construção para meu aplicativo da web.
Quero ter pelo menos duas configurações:
I. Configuração do desenvolvimento - carregue scripts de arquivos separados, sem concatenação,
então meu index.html seria algo como:
<!DOCTYPE html>
<html>
<head>
<script src="js/module1.js" />
<script src="js/module2.js" />
<script src="js/module3.js" />
...
</head>
<body></body>
</html>
II Configuração de produção - carregue meus scripts minificados e concatenados em um arquivo,
com index.html de acordo:
<!DOCTYPE html>
<html>
<head>
<script src="js/MyApp-all.min.js" />
</head>
<body></body>
</html>
A questão é: como posso fazer o grunhido tornar esses index.html dependendo da configuração quando executo grunt dev
ou grunt prod
?
Ou talvez eu esteja cavando na direção errada e seria mais fácil sempre gerar, MyApp-all.min.js
mas colocar dentro dele todos os meus scripts (concatenados) ou um script do carregador que carrega de forma assíncrona esses scripts a partir de arquivos separados?
Como você faz isso, pessoal?
fonte
Respostas:
Descobri recentemente essas
v0.4.0
tarefas compatíveis com o Grunt :pré-processo
grunhido-env
Abaixo estão trechos do meu
Gruntfile.js
.Configuração ENV:
Pré-processo:
Tarefas:
E no
/src/tmpl/index.html
arquivo de modelo (por exemplo):Tenho certeza de que minha configuração é diferente da maioria das pessoas, e a utilidade das opções acima dependerá da sua situação. Para mim, embora seja um código incrível, o grunhido-usemin da Yeoman é mais robusto do que eu pessoalmente preciso.
NOTA: Eu apenas descobriu as tarefas listadas acima de hoje, para que eu possa estar faltando uma característica e / ou o meu processo pode mudar no futuro. Por enquanto, estou adorando a simplicidade e os recursos que o pré-processo e o env-grunt têm a oferecer. :)
Atualização de janeiro de 2014:
Motivado por um voto negativo ...
Quando publiquei esta resposta, não havia muitas opções para o Grunt
0.4.x
que ofereciam uma solução que funcionava para minhas necessidades. Agora, meses depois, eu acho que existem mais opções por aí que poderiam ser melhores do que as que eu publiquei aqui. Enquanto eu pessoalmente ainda uso e gosto de usar essa técnica para minhas compilações , peço que os futuros leitores tenham tempo para ler as outras respostas dadas e pesquisar todas as opções. Se você encontrar uma solução melhor, poste sua resposta aqui.Atualização de fevereiro de 2014:
Não tenho certeza se será de alguma ajuda para alguém, mas criei este repositório de demonstração no GitHub que mostra uma configuração completa (e mais complexa) usando as técnicas que descrevi acima.
fonte
path : '/<%= pkg.name %>/dist/<%= pkg.version %>/<%= now %>/<%= ver %>'
que concata todos os vars (esse é o meu caminho de construção). No meu modelo que eu vou ter:<script src="http://cdn.foo.com<!-- @echo path -->/js/bulldog.min.js"></script>
. Enfim, estou feliz por ter poupado algum tempo! : Ddata
objeto diferente para dev / prod.Eu vim com minha própria solução. Ainda não polido, mas acho que vou seguir nessa direção.
Em essência, estou usando grunt.template.process () para gerar meu
index.html
de um modelo que analisa a configuração atual e produz uma lista dos meus arquivos de origem originais ou links para um único arquivo com código minificado. O exemplo abaixo é para arquivos js, mas a mesma abordagem pode ser estendida para css e quaisquer outros arquivos de texto possíveis.grunt.js
:index.js (the index task)
:Finalmente,
index.tmpl
com a lógica de geração inserida em:UPD. Descobriu que o Yeoman , que é baseado no grunhido, tem uma tarefa interna integrada que se integra ao sistema de compilação do Yeoman. Ele gera uma versão de produção de index.html a partir de informações na versão de desenvolvimento de index.html, além de outras configurações do ambiente. Um pouco sofisticado, mas interessante de se ver.
fonte
grunt.template.process()
(que é o que você está usando aqui) que tornaria isso ainda mais fácil. Você pode fazer o mesmo usando o grunt-template simplesmente passando umdata
objetodiferentepara dev / prod.Não gosto das soluções aqui (incluindo a que eu dei anteriormente ) e aqui está o porquê:
Eu descobri como resolver esses dois problemas. Configurei minha tarefa difícil para que, sempre que um arquivo for adicionado ou excluído, as tags de script sejam geradas automaticamente para refletir isso. Dessa forma, você não precisa modificar seu arquivo html ou grunt quando adicionar / remover / renomear seus arquivos JS.
Para resumir como isso funciona, tenho um modelo html com uma variável para as tags de script. Eu uso https://github.com/alanshaw/grunt-include-replace para preencher essa variável. No modo dev, essa variável vem de um padrão globbing de todos os meus arquivos JS. A tarefa de observação recalcula esse valor quando um arquivo JS é adicionado ou removido.
Agora, para obter resultados diferentes no modo dev ou prod, basta preencher essa variável com um valor diferente. Aqui está um código:
jsSrcFileArray
é o seu padrão típico de arquivo grunhido.jsScriptTags
pegajsSrcFileArray
e concatena-os juntamente comscript
etiquetas de ambos os lados.destPath
é o prefixo que eu quero em cada arquivo.E aqui está a aparência do HTML:
Agora, como você pode ver na configuração, eu gero o valor dessa variável como uma
script
etiqueta codificada quando é executada noprod
modo. No modo dev, essa variável será expandida para um valor como este:Deixe-me saber se você tiver alguma dúvida.
PS: Essa é uma quantidade louca de código para algo que eu gostaria de fazer em todos os aplicativos JS do lado do cliente. Espero que alguém possa transformar isso em um plugin reutilizável. Talvez eu vá algum dia.
fonte
I've set up my grunt task so that every time a file is added or deleted, the script tags automatically get generated to reflect that
Como você fez isso?<script>
tags HTML ?destPath
dejsScriptTags
e trocougrunt.file.expandMapping
comgrunt.file.expand
que os arquivos que eu queria já estavam nos lugares corretos. Isso simplificou bastante as coisas. Obrigado @DanielKaplan, você salvou-me uma enorme quantidade de tempo :)Eu tenho me perguntado a mesma pergunta há algum tempo, e acho que esse plug-in do grunhido pode ser configurado para fazer o que você deseja: https://npmjs.org/package/grunt-targethtml . Ele implementa tags html condicionais, que dependem do destino pesado.
fonte
Eu estava procurando uma solução mais simples e direta, então combinei a resposta desta pergunta:
Como colocar se outro bloco no gruntfile.js
e veio com as seguintes etapas simples:
Use a seguinte lógica no bloco de concat / cópia do Gruntfile.js para o seu arquivo index.html:
execute 'grunt --Release' para escolher o arquivo index-production.html e deixe o sinalizador para ter a versão de desenvolvimento.
Não há novos plugins para adicionar ou configurar, nem novas tarefas grunhidas.
fonte
Essa tarefa difícil chamada scriptlinker parece uma maneira fácil de adicionar os scripts no modo dev. Você provavelmente pode executar uma tarefa de concat primeiro e depois apontá-la para o arquivo concatenado no modo prod.
fonte
<!--SINON COMPONENT SCRIPTS-->
e<!--SPEC SCRIPTS-->
. E aqui está a tarefa do Grunt que faz isso (uma tarefa de trabalho real, em oposição às coisas dos documentos). Espero que ajude;)grunt-dom-munger lê e manipula HTML com seletores CSS. Ex. leia as tags do seu html. Remova nós, adicione nós e muito mais.
Você pode usar o grunt-dom-munger para ler todos os seus arquivos JS vinculados pelo index.html, aumentá-los e depois usar o grunt-dom-munger novamente para modificar o index.html para vincular apenas o JS minificado
fonte
Encontrei um plugin chamado grunt-dev-prod-switch. Tudo o que faz é comentar alguns blocos que ele procura, com base na opção --env que você passa para o grunhido (embora isso limite o desenvolvimento, a produção e o teste).
Depois de configurá-lo como explicado aqui , você pode executar, por exemplo:
grunt serve --env=dev
, e tudo o que faz é comentar os blocos envolvidos pore descomentará os blocos envolvidos por
Também funciona em javascript, eu o uso para configurar o endereço IP correto para conectar-se à minha API de back-end. Os blocos mudam para
No seu caso, seria tão simples quanto isto:
fonte
grunt-bake é um script fantástico que funcionaria muito bem aqui. Eu o uso no meu script de construção automática do JQM.
https://github.com/imaginethepoet/autojqmphonegap
Dê uma olhada no meu arquivo grunt.coffee:
Ele analisa todos os arquivos em base.html e os suga para criar o index.html que funciona de maneira fantástica para aplicativos de várias páginas (phonegap). Isso permite um desenvolvimento mais fácil, pois todos os desenvolvedores não estão trabalhando em um aplicativo de página única longa (evitando muitos check-ins de conflito). Em vez disso, você pode dividir as páginas e trabalhar em pequenos pedaços de código e compilar a página inteira usando um comando watch.
O Bake lê o modelo em base.html e injeta as páginas html do componente em exibição.
Demonstrações móveis do jQuery
app.initialize ();
Você pode dar um passo adiante e adicionar injeções em suas páginas para "menus", "pop-ups" etc., para que você possa realmente dividir as páginas em componentes gerenciáveis menores.
fonte
Use uma combinação de wiredep https://github.com/taptapship/wiredep e usemin https://github.com/yeoman/grunt-usemin para que o grunhido cuide dessas tarefas. O Wiredep adicionará suas dependências um arquivo de script por vez e o usemin concatenará todas elas em um único arquivo para produção. Isso pode ser feito com apenas alguns comentários html. Por exemplo, meus pacotes do bower são incluídos automaticamente e adicionados ao html quando executo
bower install && grunt bowerInstall
:fonte
Esta resposta não é para noobs!
Usar modelo Jade ... passar variáveis para um modelo Jade é um caso de uso padrão
Estou usando o grunhido (grunt-contrib-jade), mas você não precisa usar o grunhido. Basta usar o módulo jpm npm padrão.
Se você estiver usando o grunhido, seu arquivo de grunt gostaria de algo como ...
Agora podemos acessar facilmente os dados passados por grunt no modelo Jade.
Assim como a abordagem usada pelo Modernizr, defino uma classe CSS na tag HTML de acordo com o valor da variável passada e posso usar a lógica JavaScript a partir daí, dependendo da presença ou não da classe CSS.
Isso é ótimo se você usar Angular, pois você pode usar ng-if para incluir elementos na página com base na presença da classe.
Por exemplo, posso incluir um script se a classe estiver presente ...
(Por exemplo, eu posso incluir o script de recarga ao vivo no dev, mas não na produção)
fonte
Considere processhtml . Permite definir vários "destinos" para compilações. Os comentários são usados para incluir ou excluir condicionalmente material do HTML:
torna-se
Ele até pretende fazer coisas bacanas como esta (veja o README ):
fonte