Estoy tratando de usar Grunt como herramienta de compilación para mi aplicación web.
Quiero tener al menos dos configuraciones:
I. Configuración de desarrollo : cargar scripts de archivos separados, sin concatenación,
entonces mi index.html se vería así:
<!DOCTYPE html>
<html>
<head>
<script src="js/module1.js" />
<script src="js/module2.js" />
<script src="js/module3.js" />
...
</head>
<body></body>
</html>
II Configuración de producción : cargar mis scripts minificados y concatenados en un archivo,
con index.html en consecuencia:
<!DOCTYPE html>
<html>
<head>
<script src="js/MyApp-all.min.js" />
</head>
<body></body>
</html>
La pregunta es, ¿cómo puedo hacer que Grunt haga estos index.html dependiendo de la configuración cuando ejecuto grunt dev
o grunt prod
?
¿O tal vez estoy cavando en la dirección incorrecta y sería más fácil generar siempre, MyApp-all.min.js
pero poner dentro de mí todos mis scripts (concatenados) o un script de cargador que carga de forma asíncrona esos scripts de archivos separados?
¿Cómo lo hacen, chicos?
fuente
Respuestas:
Recientemente descubrí estas
v0.4.0
tareas compatibles con Grunt :gruñir-preproceso
gruñido env
Debajo hay fragmentos de mi
Gruntfile.js
.Configuración de ENV:
Preproceso:
Tareas:
Y en el
/src/tmpl/index.html
archivo de plantilla (por ejemplo):Estoy seguro de que mi configuración es diferente a la de la mayoría de las personas, y la utilidad de lo anterior dependerá de su situación. Para mí, si bien es un código increíble, Yeoman Grunt-usemin es más robusto de lo que personalmente necesito.
NOTA: Me acaba de descubrir las tareas mencionadas anteriormente hoy, así que puede ser que falte una característica y / o de mi proceso puede cambiar en el futuro. Por ahora, me encanta la simplicidad y las características que Grunt-preprocess y Grunt-env tienen para ofrecer. :)
Actualización de enero de 2014:
Motivado por un voto negativo ...
Cuando publiqué esta respuesta, no había muchas opciones para Grunt
0.4.x
que ofrecieran una solución que funcionara para mis necesidades. Ahora, meses después, supongo que hay más opciones que podrían ser mejores que las que he publicado aquí. Si bien todavía uso y disfruto personalmente el uso de esta técnica para mis compilaciones , les pido a los futuros lectores que se tomen el tiempo para leer las otras respuestas dadas y para investigar todas las opciones. Si encuentra una solución mejor, publique su respuesta aquí.Actualización de febrero de 2014:
No estoy seguro de si será de alguna ayuda para alguien, pero he creado este repositorio de demostración en GitHub que muestra una configuración completa (y más compleja) utilizando las técnicas que he descrito anteriormente.
fuente
path : '/<%= pkg.name %>/dist/<%= pkg.version %>/<%= now %>/<%= ver %>'
que concatena todos los vars (esa es mi ruta de compilación). En mi plantilla Tendré:<script src="http://cdn.foo.com<!-- @echo path -->/js/bulldog.min.js"></script>
. De todos modos, ¡estoy feliz de poder ahorrarte algo de tiempo! : Ddata
objeto diferente para dev / prod.Se me ocurrió mi propia solución. Todavía no está pulido, pero creo que voy a avanzar en esa dirección.
En esencia, estoy usando grunt.template.process () para generar mi
index.html
desde una plantilla que analiza la configuración actual y produce una lista de mis archivos fuente originales o enlaces a un solo archivo con código minificado. El siguiente ejemplo es para archivos js, pero el mismo enfoque se puede extender a css y cualquier otro archivo de texto posible.grunt.js
:index.js (the index task)
:Finalmente,
index.tmpl
con la lógica de generación integrada:UPD Descubrí que Yeoman , que se basa en el gruñido, tiene una tarea usemin incorporada que se integra con el sistema de construcción de Yeoman. Genera una versión de producción de index.html a partir de la información en la versión de desarrollo de index.html, así como otras configuraciones del entorno. Un poco sofisticado pero interesante de ver.
fuente
grunt.template.process()
(que es lo que estás usando aquí) que lo haría aún más fácil. Podrías hacer lo mismo usando grunt-template simplemente pasando undata
objetodiferentepara dev / prod.No me gustan las soluciones aquí (incluida la que di anteriormente ) y he aquí por qué:
He descubierto cómo resolver estos dos problemas. He configurado mi tarea gruñona para que cada vez que se agregue o elimine un archivo, las etiquetas de script se generen automáticamente para reflejar eso. De esta manera, no necesita modificar su archivo html o su archivo de gruñido cuando agrega / elimina / renombra sus archivos JS.
Para resumir cómo funciona, tengo una plantilla html con una variable para las etiquetas de script. Yo uso https://github.com/alanshaw/grunt-include-replace para llenar esa variable. En el modo de desarrollo, esa variable proviene de un patrón global de todos mis archivos JS. La tarea de observación recalcula este valor cuando se agrega o elimina un archivo JS.
Ahora, para obtener resultados diferentes en modo dev o prod, simplemente llene esa variable con un valor diferente. Aquí hay un código:
jsSrcFileArray
es tu típico patrón gruñido de gruñidojsScriptTags
toma eljsSrcFileArray
y los concatena junto conscript
etiquetas en ambos lados.destPath
es el prefijo que quiero en cada archivo.Y así es como se ve el HTML:
Ahora, como puede ver en la configuración, genero el valor de esa variable como una
script
etiqueta codificada cuando se ejecuta enprod
modo. En modo dev, esta variable se expandirá a un valor como este:Hazme saber si tienes alguna pregunta.
PD: Esta es una cantidad loca de código para algo que me gustaría hacer en cada aplicación JS del lado del cliente. Espero que alguien pueda convertir esto en un complemento reutilizable. Quizás lo haga algún día.
fuente
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
¿Cómo hiciste eso?<script>
etiquetas HTML ?destPath
dejsScriptTags
e intercambiadogrunt.file.expandMapping
congrunt.file.expand
que los archivos que quería ya estaban en los lugares correctos. Esto simplificó mucho las cosas. Gracias @DanielKaplan, me has ahorrado una gran cantidad de tiempo :)Me he estado haciendo la misma pregunta por un tiempo, y creo que este plugin Grunt podría configurarse para hacer lo que quieras: https://npmjs.org/package/grunt-targethtml . Implementa etiquetas html condicionales, que dependen del objetivo gruñido.
fuente
Estaba buscando una solución más simple y directa, así que combiné la respuesta de esta pregunta:
Cómo colocar si otro bloque en gruntfile.js
y se me ocurrieron los siguientes pasos simples:
Use la siguiente lógica en el bloque concat / copy de su Gruntfile.js para su archivo index.html:
ejecute 'grunt --Release' para elegir el archivo index-production.html y deje el indicador para tener la versión de desarrollo.
Sin nuevos complementos para agregar o configurar y sin nuevas tareas de gruñido.
fuente
Esta tarea gruñona llamada scriptlinker parece una manera fácil de agregar los scripts en modo dev. Probablemente podría ejecutar primero una tarea concat y luego apuntarla a su archivo concatenado en modo prod.
fuente
<!--SINON COMPONENT SCRIPTS-->
y<!--SPEC SCRIPTS-->
. Y aquí está la tarea de Grunt que lo hace (una tarea real, a diferencia de las cosas en los documentos). Espero que ayude;)grunt-dom-munger lee y manipula HTML con selectores CSS. Ex. lee las etiquetas de tu html. Eliminar nodos, agregar nodos y más.
Puede usar grunt-dom-munger para leer todos sus archivos JS vinculados por su index.html, uglificarlos y luego usar grunt-dom-munger nuevamente para modificar su index.html para vincular solo el JS minificado
fuente
Encontré un plugin grunt llamado grunt-dev-prod-switch. Todo lo que hace es comentar ciertos bloques que busca en función de una opción --env que pasa a gruñir (aunque lo limita a dev, prod y test).
Una vez que lo configure como se explica aquí , puede ejecutar, por ejemplo:
grunt serve --env=dev
, y todo lo que hace es comentar los bloques que están envueltos pory eliminará los bloques que están envueltos por
También funciona en javascript, lo uso para configurar la dirección IP correcta para conectarme a mi API de back-end. Los bloques simplemente cambian a
En su caso, sería tan simple como esto:
fuente
Grunt-Bake es un fantástico script de gruñido que funcionaría muy bien aquí. Lo uso en mi script de creación automática de JQM.
https://github.com/imaginethepoet/autojqmphonegap
Echa un vistazo a mi archivo grunt.coffee:
Esto examina todos los archivos en base.html y los absorbe para crear index.html funciona de maravilla para aplicaciones multipágina (phonegap). Esto permite un desarrollo más fácil ya que todos los desarrolladores no están trabajando en una sola aplicación de página larga (evitando muchos registros de conflictos) En cambio, puede dividir las páginas y trabajar en fragmentos de código más pequeños y compilarlos en la página completa utilizando un comando watch.
Bake lee la plantilla de base.html e inyecta las páginas html del componente de servicio.
Demostraciones móviles de jQuery
app.initialize ();
Puede llevar esto un paso más allá y agregar inyecciones en sus páginas para "menús", "ventanas emergentes", etc., de modo que realmente pueda dividir las páginas en componentes manejables más pequeños.
fuente
Use una combinación de wiredep https://github.com/taptapship/wiredep y usemin https://github.com/yeoman/grunt-usemin para que Grunt se encargue de estas tareas. Wiredep agregará sus dependencias un archivo de script a la vez, y usemin las concatenará todas en un solo archivo para producción. Esto se puede lograr con solo algunos comentarios html. Por ejemplo, mis paquetes Bower se incluyen automáticamente y se agregan al html cuando ejecuto
bower install && grunt bowerInstall
:fuente
¡Esta respuesta no es para novatos!
Use plantillas de Jade ... pasar variables a una plantilla de Jade es un caso de uso estándar pantanoso
Estoy usando grunt (grunt-contrib-jade) pero no tienes que usar grunt. Simplemente use el módulo estándar npm jade.
Si usa grunt, entonces su archivo de gruñido le gustaría algo como ...
Ahora podemos acceder fácilmente a los datos pasados por gruñido en la plantilla Jade.
Al igual que el enfoque utilizado por Modernizr, configuro una clase CSS en la etiqueta HTML de acuerdo con el valor de la variable pasada y puedo usar la lógica de JavaScript a partir de si la clase CSS está presente o no.
Esto es genial si usa Angular ya que puede hacer ng-if para incluir elementos en la página en función de si la clase está presente.
Por ejemplo, podría incluir un script si la clase está presente ...
(Por ejemplo, podría incluir el script de recarga en vivo en dev pero no en producción)
fuente
Considere el procesohtml . Permite la definición de múltiples "objetivos" para compilaciones. Los comentarios se usan para incluir o excluir condicionalmente material del HTML:
se convierte
Incluso pretende hacer cosas ingeniosas como esta (ver el archivo README ):
fuente