javascript - serve - que es gulp
cómo minificar los archivos js en orden a través de grunt-contrib-uglify? (9)
¡Buena pregunta!
1) Uglify reordenará las funciones en el archivo de destino para que las definiciones de las funciones estén en la parte superior y la ejecución de las funciones en la parte inferior, pero parece que conservará el orden de las ejecuciones de funciones.
Esto significa que la función que jQuery ejecuta para definir sus funciones globales se pondrá primero si se asegura de que jQuery se mencione primero en la configuración de Uglify en Gruntfile.
Yo uso esta configuración:
uglify: {
options: {
sourceMap: true
},
build: {
files: {
''public/all.min.js'': [''public/js/vendor/jquery-1.10.2.min.js'', ''public/js/*.js''],
}
}
}
2) No creo que haya una forma definida de lograr esto. Depende de qué marco web, marco de plantillas y qué tipo de requisitos tiene. Uso express + jade y en mi diseño principal de jade tengo:
if process.env.NODE_ENV === ''production''
script(src=''/all.min.js'')
else
script(src=''/js/vendor/jquery-1.10.2.min.js'')
script(src=''/js/someScript.js'')
script(src=''/js/otherScript.js'')
En mi package.json tengo:
"scripts": {
"postinstall": "grunt"
},
Esto significa que cuando ejecuto npm install
en deploy (en Heroku), el grunt se ejecuta para minify / concat y cuando la aplicación se inicia con NODE_ENV=production
se utiliza el javascript minimizado del lado del cliente. A nivel local, me sirven los javascripts originales del lado del cliente para una fácil depuración.
Las dos desventajas son:
- Tengo que mantener sincronizadas las dos listas de archivos de script (en el Gruntfile y en el layout.js) Resuelvo esto usando
*.js
en el Gruntfile, pero puede que no sea apto para todos. Puede poner la lista de javascripts en Gruntfile y crear una plantilla de jade a partir de esto, pero parece excesiva para la mayoría de los proyectos. - Si no confías en tu configuración de Grunt, básicamente tienes que probar la ejecución de la aplicación usando
NODE_ENV=production
localmente para verificar que la minificación funcionó de la manera que pretendías.
Tengo un directorio como el siguiente:
/folder/b.js
/folder/jQuery.js
/folder/a.js
/folder/sub/c.js
Quiero minificar todos estos archivos js en un archivo js en orden :
jQuery.js -> a.js -> b.js -> c.js
P:
1. ¿Cómo puedo hacerlo a través de grunt-contrib-uglify? (De hecho, hay muchos archivos, no es práctico especificar todos los filepaths de origen de forma individual)
2.btw, ¿cómo puedo obtener archivos no minificados cuando se depuran y obtener archivos únicos minificados cuando se publican y no es necesario cambiar la etiqueta de script en html (y cómo escribir la etiqueta de script)?
Esta fue la respuesta de @ 1469 pero no dejó en claro por qué funciona esto. Use concat para poner todos los archivos js en uno, este módulo hace esto en el orden de los nombres de los archivos, por lo que pongo un prefijo para los nombres de los archivos en función de los pedidos. Creo que incluso tiene otras opciones para ordenar.
concat: {
js: {
options: {
block: true,
line: true,
stripBanners: true
},
files: {
''library/dist/js/scripts.js'' : ''library/js/*.js'',
}
}
},
Luego usa uglify para crear la versión fea minificada:
uglify: {
dist: {
files: {
''library/dist/js/scripts.min.js'': [
''library/js/scripts.js''
]
},
options: {
}
}
},
Esto podría estar solo remotamente relacionado con tu pregunta, pero yo quería algo similar. Solo mi orden fue importante de la siguiente manera:
Estaba cargando todos los archivos del proveedor (angular, jquery y sus respectivos complementos relacionados) con un comodín ( [''vendor/**/*.js'']
). Pero algunos complementos tenían nombres que los hacían cargar antes de angular y jquery. Una solución es cargarlos manualmente primero.
[''vendor/angular.js'', ''vendor/jquery.js'', ''vendor/**/*.js]
Afortunadamente angulares y jquery se cargan dos veces lo suficientemente bien. Editar: aunque en realidad no es la mejor práctica cargar esas grandes bibliotecas dos veces, lo que provoca que el archivo minimizado sea innecesario. (¡Gracias @Kano por señalar esto!)
Otro problema fue que la orden de los clientes era importante, de manera que requería que el archivo de la aplicación principal se cargara por última vez, después de que todas sus dependencias se hayan cargado. La solución a eso era excluir y luego incluir:
[''app/**/*.js'', ''!app/app.js'', ''app/app.js'']
Esto evita que app.js
se cargue junto con todos los otros archivos, y solo luego lo incluye al final.
Esto se puede hacer usando las siguientes tareas de Grunt:
- https://github.com/gruntjs/grunt-contrib-concat concatena archivos
- doc minimiza los archivos concatenados
EDITAR
Por lo general, ejecuto todos mis archivos a través de una tarea de concatenación de Grunt usando grunt-contrib-concat . Luego tengo otra tarea para uglify el archivo concatenado usando doc .
Me encontré con el mismo problema. Una solución rápida es cambiar los nombres de los archivos: utilicé 1.jquery.min.js
, 2.bootstrap.min.js
, etc.
No creo que puedas hacer esto solo con la tarea de uglify, pero tienes una multitud de opciones que pueden llevarte al resultado deseado.
Un posible flujo de trabajo sería primero concatenar (grunt-contrib-concat) los archivos en orden en un solo archivo, y poner este archivo concatenado a través de uglify. Puede definir el orden para concat en su Gruntfile, o puede usar uno de esos complementos:
El primero sería https://github.com/yeoman/grunt-usemin , donde puedes especificar el orden en tu archivo HTML, poner algunos comentarios alrededor de tu bloque de script. Los chicos de Google lo hicieron y es muy agradable de usar.
El segundo sería https://github.com/trek/grunt-neuter , donde puede definir algunas dependencias con require, pero sin la mayor parte de require.js. Requiere cambios en su código JS, por lo que podría no gustarle. Yo iría con la opción uno.
Parece que la segunda parte de su pregunta aún no ha sido respondida. Pero déjame probar uno por uno.
En primer lugar, puede unir y agrupar una gran cantidad de archivos js en uno como se explica anteriormente mediante la respuesta concat. También debería ser posible usar doc porque parece tener comodines. Puede que tenga que experimentar con la opción ''expand = true'' y comodines. Eso cuida tu primera pregunta.
Para la segunda parte, digamos que se unió y uglified en big-ugly.js
Ahora en su html puede agregar las siguientes directivas:
<!-- build:js:dist big-ugly.js -->
<script src="js1.js"></script>
<script src="js2.js"></script>
<!-- etc etc -->
<script src="js100.js"></script>
<!-- /build -->
Y luego páselo a través del preprocesador de grunt html en https://www.npmjs.com/package/grunt-processhtml como parte de tus trabajos de rutina.
Este preprocesador reemplazará todo el bloque con
<script src="big-ugly.js"></script>
Lo que significa que el archivo html debe ser semánticamente equivalente, antes y después de los trabajos de rutina; es decir, si la página funciona correctamente en la forma nativa (para la depuración), entonces la página transformada debe funcionar correctamente después del gruñido, sin que sea necesario que cambie manualmente ninguna etiqueta.
Probablemente no le va a gustar esto, pero la mejor manera es definir sus archivos fuente js como módulos AMD y usar Requirejs para administrar el orden en el que se cargan. La tarea grunt-contrib-requirejs recurrirá su árbol de dependencias y concatenará los archivos js en el orden necesario en un gran archivo js. Luego usará uglify (en realidad r.js tiene uglify incorporado) para minimizar el archivo grande.
https://github.com/danheberden/yeoman-generator-requirejs tiene un buen ejemplo de gruntfile y archivos de plantillas js para trabajar.
EDITAR
Recientemente comencé a usar módulos CommonJS en lugar de AMD, ya que está mucho más cerca de las especificaciones del módulo ES6. Puede obtener los mismos resultados (1 gran archivo js concatenado + concatenado) ejecutando los módulos de Browserify través de Browserify . Hay complementos tanto para grunt como para gulp para administrar la tarea por usted.
EDITAR
Me gustaría agregar que si su sitio está escrito usando ES6, ese Rollup es el mejor paquete concatenador nuevo. Además de agrupar sus archivos, también realizará temblores de árbol, eliminando partes de las bibliotecas que utiliza si se incluyen a través de una declaración de import
. Esto reduce su base de código a justo lo que necesita sin la cantidad de código que nunca usará.
Si su problema era que tenía proveedores que necesitaban cargarse en orden (digamos jquery antes de cualquier complemento jquery). Lo resolví poniendo jquery en su propia carpeta llamada ''! Jquery'', poniéndolo efectivamente en la parte superior de la pila. Entonces acabo de usar concat como lo haría normalmente:
concat: {
options: {
separator: '';'',
},
build: {
files: [
{
src: [''js/vendor/**/*.js'', ''js/main.min.js''],
dest: ''js/global.min.js''
}
]
}
},