gruntjs yeoman grunt-usemin

gruntjs - usemin y reescribiendo urls de imágenes en archivos CSS de proveedores usando Grunt



yeoman grunt-usemin (6)

grunt-usemin me ayuda a transformar

<link href="/dependencies/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" /> <link href="/dependencies/nanoscroller/bin/css/nanoscroller.css" rel="stylesheet" /> <link href="/dependencies/dropzone/downloads/css/dropzone.css" rel="stylesheet" />

a un js perfectamente combinado y minificado:

<link href="scripts/8e1991c7.libraries.js" rel="stylesheet" />

Después de concat, cssmin y uglify tengo una estructura de carpetas casi perfecta a excepción de las imágenes y sus ubicaciones.

Aquí está mi problema:

Todos los archivos css de este proveedor incluyen ubicaciones de imágenes. Lo malo es que todos comparten diferentes tipos de ubicaciones. Algunos de ellos están usando imágenes dentro de la carpeta css mientras que otros están usando la carpeta img dentro.

¿Cómo puedo configurar el grunt usemin para reescribir todas las imágenes urls?


Investigué un poco y encontré un par de tareas que parecen terminar el trabajo: https://github.com/yeoman/grunt-filerev y https://github.com/richardbolt/grunt-cssurlrev . El único problema con esto es que tendrás que configurar las rutas dentro de tu Gruntfile manualmente, así:

grunt.initConfig({ filerev: { images: { src: [''img1.png'', ''img2.png''], dest: ''tmp'' } }, cssurlrev: { dist: { src: [''public/css/*.css''] }, } });

Que yo sepa, no hay un complemento que haga esta tarea automáticamente.


Tuve que implementar una nueva tarea. Esta es mi implementación preliminar.

grunt.registerMultiTask(''rewriteCssUrl'', ''rewrite url in css'', function () { var options = this.options({ assets: grunt.filerev ? grunt.filerev.summary : {}, postFilter: function identity(input){ return input} }); var self = this; var assets = options.assets; self.filesSrc.forEach(function (file) { var css = grunt.file.read(file); var original = css; css = css.replace(/(?:src=|url/(/s*)[''"]?([^''"/)]+)[''"]?/s*/)?/gm, function (match, src) { var key = path.join(path.dirname(file), src); var asset = assets[path.normalize(key)]; var val = options.postFilter(asset); return match.replace(src, val || match); }); if(original !== css) { grunt.log.writeln(''✔ ''.green + file + ('' was changed.'').grey); grunt.file.write(file, css); } }); });


He resuelto el problema usando lo siguiente.

useminPrepare: { html: ''src/index.html'', options: { dest: ''build'', flow: { html: { steps: { js: [''concat'', ''uglifyjs''], css: [''cssmin''] }, post: {} } } } }, cssmin: { options: { root: ''src'' } }

Primero, estamos anulando el flow useminPrepare , eliminando la tarea concat de los flujos css. Esto es necesario porque concat destruirá la información de ruta relativa. Como cssmin se combinará con múltiples archivos, la tarea de concat con sepearte solo es dañina. ( https://github.com/yeoman/grunt-usemin/issues/225 )

Por último, le estamos diciendo a cssmin dónde está la "raíz" de su proyecto del Gruntfile. Esto ayuda a cssmin reescribir las URL relativas que encuentra en relación con este directorio "raíz".


Mi enfoque para este problema consistía básicamente en crear un styles/select2/select2.css por styles/select2/select2.css para cada estilo de proveedor, y luego Grunt puede copiar todas las imágenes relevantes en styles/select2 (sin tener que preocuparse por rutas relativas ni sobrescribir, etc.) como parte del guion Es decir:

app / index.html

<!-- build:css(.tmp) styles/select2/select2.css --> <link rel="stylesheet" href="bower_components/select2/select2.css"> <!-- endbuild -->

Gruntfile.js

Agregue una nueva tarea de copy que copiará los estilos de proveedor en el directorio .tmp antes de que se minimicen con cssmin :

copy: { // this copies bower_components/*.css into .tmp so they can be compiled styles: { expand: true, cwd: ''<%= yeoman.app %>'', dest: ''.tmp/'', src: [ ''styles/{,*/}*.css'', ''bower_components/**/*.css'' ] }, dist: ...

Y luego, una vez que estén minimizados, copie los activos relevantes (que en este caso asumo que son solo imágenes PNG y GIF):

// and once we have compiled all of our stylesheets, we need to also copy over any necessary image files distAssets: { expand: true, cwd: ''<%= yeoman.app %>/bower_components'', dest: ''<%= yeoman.dist %>/styles'', src: [ ''**/*.png'', ''**/*.gif'' ] } },

Finalmente, agregue las nuevas tareas en la tarea de build :

grunt.registerTask(''build'', [ ''clean:dist'', ''replace:dist'', ''copy:styles'', // -- added ''useminPrepare'', // ... etc ... ''copy'', ''rev'', ''usemin'', ''copy:distAssets'' // -- added ]);


1) Imágenes rev. Agregue rutas de imágenes a la tarea rev.

rev: { dist: { files: { src: [ ''<%= yeoman.dist %>/static/scripts/{,*/}*.js'', ''<%= yeoman.dist %>/static/styles/{,*/}*.css'', ''<%= yeoman.dist %>/static/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'', ] } } }

2) Agregue rutas de archivo que incluyan ubicaciones de imágenes en la tarea usemin.

usemin: { html: [''<%= yeoman.dist %>/{,*/}*.html''], css: [''<%= yeoman.dist %>/static/styles/{,*/}*.css''], options: { assetsDirs: [''<%= yeoman.dist %>'',''<%= yeoman.dist%>/static/images''], } }

3) Ejecutar gruñido.


Lo que me solucionó la aceleración de la background-image CSS fue agregar un patrón de CSS en las options , que busca todas las referencias de activos en el CSS y las reemplaza con los activos con revoluciones.

// Performs rewrites based on rev and the useminPrepare configuration usemin: { ... ... options: { ... ... // This is so we update image references in our ng-templates patterns: { js: [ [/(assets//images//.*?/.(?:gif|jpeg|jpg|png|webp|svg))/gm, ''Update the JS to reference our revved images''] ], css: [ [/(assets//images//.*?/.(?:gif|jpeg|jpg|png|webp|svg))/gm, ''Update the CSS to reference our revved images''] ] } } },