Este é o primeiro post de uma series com 3 post sobre Grunt.

Todo o código utilizado encontra-se no Github


Em uma simples frase, Grunt é um automatizador de tarefas! Seu objetivo é automatizar tarefas repetitivas, por exemplo: Compactar arquivos, concatenar, minificar, executar testes e centenas de outras tarefas, tudo isso de uma forma altamente flexível!

Problema

São diversos problemas que esta ferramenta se propõe a solucionar, tudo depende do que você está precisando.

Eu (como desenvolvedor web) tenho de: * Compilar meus arquivos sass e coffee * Executar testes * Otimizar imagens * Compilar templates handlebars

Para publicar um website: * Minificar js e css * Concatenar * Lint * Compactar arquivos no formato zip * Enviar via FTP para o server

Percebe como são repetitivas estas tarefas? Com Grunt o podemos automatizar tudo isso.

Primeiros passos

Grunt roda como um modulo Nodejs, sua instalação é bem simples: npm install -g grunt-cli, na página Getting started você encontra mais detalhes sobre a instalação.

Não vou entrar em detalhes sobre o que é Nodejs ou como instalá-lo (sugiro instalação via Chocolatey cinst nodejs.install) pois não é o objetivo deste post.

Preparando o ambiente

Tipicamente Grunt requer dois arquivos package.json responsável por descrever o projeto e Gruntfile.js onde você irá definir suas tasks e carregar os plugins.

package.json

{
  "author": "Riderman de Sousa Barbosa",
  "name": "grunt-started",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.0"
  }
}

A propriedade mais importante é a devDependencies que contém todas as dependências do seu projeto. Repare que nossa primeira dependência é o próprio Grunt. Isto porque grunt-cli serve apenas para rodar a versão ao lado do Gruntfile.js.

> Til ~ indica que deve ser maior ou igual a versão indicada e menor do que a próxima grande versão. Mais detalhes neste link

Instalando o Grunt em nosso projeto

O próximo passo é pedir ao npm para instalar todas as dependências descritas em nosso package.json (em nosso caso apenas o grunt);

npm install

Primeira task (coffee)

Apenas o grunt não nos ajuda em nada, para fazer algo mais real precisamos de plugins. Por exemplo, se quisermos compilar nossos arquivos .coffee para .js precisamos de um plugin para realizar esta tarefa.

Existem diversos plugins disponíveis, desde cópia de arquivos até mesmo enviar arquivos por FTP. O time do Grunt mantém o grunt-contrib, uma coleção de 26 plugins (até a data de publicação deste post), cada um responsável por uma tarefa. Além destes, na página do projeto você pode encontrar dezenas (ou centenas) de outros plugins. E se não achar o que deseja, você pode inclusive criar sua própria task (mais detalhes no último post da série).

Para esta primeira task vamos compilar nossos arquivos .coffee para .js.

Instalando o plugin

Primeiramente precisamos instalar o plugin:

npm install grunt-contrib-coffee --save-dev

--save-dev adiciona este plugin como dependência no nosso arquivo package.json. Após executado o arquivo terá uma linha extra:

"devDependencies": {
  "grunt": "~0.4.0",
  "grunt-contrib": "~0.6.1"  <-- Linha extra
}

Configurando Como dito anteriormente, grunt requer dois arquivos package.json e o Gruntfile.js. Então crie um novo arquivo com o nome Gruntfile.js e o seguinte conteúdo:

module.exports = function(grunt) {
  // Configurações
  grunt.initConfig({
    coffee:{
        compile: {
            files: {
                "main.js": "main.coffee"
            }
        }
    }
  });

  // Plugins
  grunt.loadNpmTasks('grunt-contrib-coffee');
};

O arquivo nada mais é do que uma configuração das tasks. Como configurar depende de cada plugin, neste caso a documentação deste plugin encontra-se neste link

main.js

Como ainda não temos o arquivo, vamos criá-lo:

calc = (a, b) -> a + b
result = calc 1, 2
console.log result

Simples, e não faz nada útil. Mas para teste é suficiente! :)

Testando

grunt coffee

E um novo arquivo main.js é criado.

Segunda task (watch)

Para esta segunda task, vamos vigiar este arquivo, caso sofra alteração grunt deverá compilar novamente para .js. Para realizar esta tarefa precisaremos do plugin grunt-contrib-watch.

npm install grunt-contrib-watch --save-dev

Novamente uma nova linha é adicionada em nosso package.json:

...
  "devDependencies": {
    ...
    "grunt-contrib-watch": "~0.3.1" <-- Linha adicionada
    .

..

Da mesma forma, precisaremos carregar a task para o nodejs. Altere o arquivo Gruntfile.js:

module.exports = function(grunt) {
  // Configurações
  grunt.initConfig({
    coffee:{
        compile: {
            files: {
                "main.js": "main.coffee"
            }
        }
    },
    watch: { // <---- Nova configuração ----
        files: 'main.coffee',
        tasks: ['coffee']
    }

  });

  // Plugins
  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-contrib-watch'); // <-- Carrega a task para o NodeJS ----
};

Agora é só utilizar:

grunt watch

Tente realizar uma modificação qualquer no arquivo main.coffee e veja o que acontece.

Tasks uglify e concat

Agora que já estamos bons, vamos adicionar mais dois plugins, instale o grunt-contrib-uglify e o grunt-contrib-concat. Baixe também o jquery e adicione-o ao nosso projeto.

Após feita a instalação, modifique seu Gruntfile.js

uglify: {
    my_target: {
      files: {
        'main.min.js': ['main.js']
      }
    }
  }
concat: {
        basic: {
            src: ['jquery-1.9.1.js', 'main.js'],
            dest: 'all.js'
        }
    }
    ...
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');

Então é só rodar: grunt uglify ou grunt concat.

Por enquanto é só, se desejar todo o código utilizado neste post encontra-se neste link. No próximo post da série veremos como executar várias tasks de uma vez, executar tasks seguindo uma configuração etc.. Ficará bem mais interessante e faremos algo útil :).

Referências

  1. Grow Up With Grunt by Ben Alman
  2. Build Podcast 021 Gruntjs
  3. Grunt - The Basics
  4. Frequently Asked Questions
  5. GruntJs ‘grunt’ cmd opens Visual Studio?
  6. A Tutorial for Getting Started with Grunt[](null)