Flujo de trabajo con grunt

Categories:

Ya revisamos algunos módulos de grunt de manera independiente falta integrarlos como parte de un flujo de trabajo – workflow -.

Aunque el flujo de trabajo varía dependiendo del proyecto o equipo de trabajo, esto te puede
servir de referencia para incorporar grunt a tu flujo de trabajo y que lo ajustes a tus necesidades.

Un escenario sería estar trabajando en el Front End – HTML, CSS, JavaScript -. Durante el desarrollo queremos visualizar los cambios en el navegador. Dependiendo de la(s) librería(s) y / o archivo(s) que estemos utilizando para el estilo o funcionalidad necesitaríamos concatenar y reducir los archivos para que únicamente se utilice una hoja de estilos y un archivo JavaScript en el documento final.

Proceso

1. Observar los archivos del proyecto – HTML, CSS, JS -.
2. Si hay cambios en alguno de estos archivos actualizar la visualización en el navegador.
3. Si los cambios son en las hojas de estilo:
3a. Concatenar las hojas de estilo para que el documento HTML únicamente utilice una.
3b. Reducir el tamaño – minificar – la hoja de estilo resultante.
4. Si hay cambios en los archivos JavaScript:
4a. Concatenar y reducir – minificar – el tamaño de los archivos de JavaScript para que el documento HTML únicamente utilice uno.
5. Borrar los archivos temporales que se pudieron generar en el proceso.
6. Incluir las tareas de las pruebas para que se ejecuten de manera automática.

Implementación

1. Observar los archivos HTML, CSS, JS.
2. Actualizar la visualización en el navegador.

watch: {
  js: {
    files: ["js/demo01.js", "js/demo02.js"],
    options: {
         livereload: true,
       },
  },
  css: {
     files: ["css/demo01.css", "css/demo02.css"],
     options: {
          livereload: true,
      },
  },
  html: {
    files: ["*.html"],
    options: {
      livereload: true
    }      
  }
}

Si hay cambios en las hojas de estilo:

3a. Concatenar las hojas de estilo para que el documento HTML únicamente utilice una.

concat: {
  options: {
    separator: "\n\n", 
  },
  css: {
    src: ["css/demo01.css", "css/demo02.css"], 
    dest: "css/demo.tmp.css"
  }
}

3b. Minificar la hoja de estilo generada.

cssmin: {
  add_banner: {
     options: {
       banner: "/* Última actualización: <%= grunt.template.today('yyyy-mm-dd hh:mm:ss') %> */"
     },
    files: {
      'css/demo.min.css': ['css/demo.tmp.css']
    }
  }
}

Para concatenar y minificar las hojas de estilo al momento que se realiza un cambio se tienen que asociar esas tareas dentro de la tarea watch.

css: {
   files: ["css/*.css"],
   tasks: ['concat', 'cssmin'],
   options: {
        livereload: true,
    },
}

4a. Concatenar y minificar los archivos de JavaScript.

uglify: {
  options: {
    compress: true, 
    mangle: false,
    beautify: false,
    banner: "/* Última actualización: <%= grunt.template.today('yyyy-mm-dd hh:mm:ss') %> */",
    sourceMap: true // Eliminar si no se necesitan source maps
  },
  js: {
    src: ["js/demo01.js", "js/demo02.js"],
    dest: "js/app.min.js"
  }          
},

Incluir la tarea de concatenación y minificación de los archivos de JavaScript dentro de la tarea watch.

js: {
  files: ["js/demo01.js", "js/demo02.js"],
  tasks: ['uglify'],
  options: {
       livereload: true,
     },
},

5. Borrar los archivos temporales que en este caso solo es demo.tmp.css.

clean: ["css/demo.tmp.css"]

6. Incluir las tareas de las pruebas – en este caso qunit – dentro de la tarea watch para que, cuando exista algún cambio en un archivo se ejecuten de manera automática.

qunit: {
  prueba: ['qunit-snippets/*.html']
}

Así quedaría el archivo Gruntfile.js * con las tareas definidas.

module.exports = function(grunt) {
  grunt.initConfig({
    watch: {
          js: {
            files: ["js/demo01.js", "js/demo02.js", "qunit-snippets/*"],
            tasks: ['uglify', 'qunit'],
            options: {
                 livereload: true,
               },
          },
          css: {
             files: ["css/demo01.css", "css/demo02.css"],
             tasks: ['concat', 'cssmin', 'clean'],
             options: {
                  livereload: true,
              },
          },
          html: {
            files: ["*.html"],
            options: {
              livereload: true
            }      
          }
      },
      concat: {
        options: {
          separator: "\n\n", 
        },
        css: {
          src: ["css/demo01.css", "css/demo02.css"], 
          dest: "css/demo.tmp.css"
        }
      },
      cssmin: {
        add_banner: {
           options: {
             banner: "/* Última actualización: <%= grunt.template.today('yyyy-mm-dd hh:mm:ss') %> */"
           },
          files: {
            'css/demo.min.css': ['css/demo.tmp.css']
          }
        }
      },
      uglify: {
        options: {
          compress: true, 
          mangle: false,
          beautify: false,
          banner: "/* Última actualización: <%= grunt.template.today('yyyy-mm-dd hh:mm:ss') %> */",
          sourceMap: true // Eliminar si no se necesitan source maps
        },
        js: {
          src: ["js/demo01.js", "js/demo02.js"],
          dest: "js/app.min.js"
        }          
      },
      clean: ["css/demo.tmp.css"],
      qunit: {
         prueba: ['qunit-snippets/*.html']
      }
  });
  
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-concat');  
    grunt.loadNpmTasks('grunt-contrib-cssmin');  
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-uglify');        
    grunt.loadNpmTasks('grunt-contrib-qunit');
    
    grunt.registerTask("default", ['watch']);
  
};

* Parece que la primer sección está comentada porque al utilizar el comodín * para seleccionar todos los archivos dentro de una carpeta – qunit-snippets/* – prismjs lo interpreta como inicio de comentario.

También es posible ejecutar alguna tarea de manera independiente utilizando el comando grunt seguido de un espacio y el nombre de la tarea que queremos ejecutar.

$ grunt watch

$ grunt concat

$ grunt cssmin

$ grunt uglify

$ grunt clean

$ grunt qunit

Las tareas para las hojas de estilo se realizan en tres partes: concatenar, minificar, limpiar archivos temporales. En este caso podemos registrar una tarea que va a realizar las tres tareas en ese orden.

grunt.registerTask("estilos", ["concat", "cssmin", "clean"]);

Ya que se registró la tarea se puede utilizar desde la terminal con el comando grunt seguido de un espacio y el nombre de esta tarea.

$ grunt estilos

De esta manera no es necesario que grunt esté observando los archivos o que se realicen todas las tareas si únicamente nos interesa realizar una tarea o un conjunto de tareas definidas en particular.

Puedes descargar el demo grunt-workflow para probar y ajustar. Recuerda instalar las dependencias con:

$ npm install