No último artigo nós falamos sobre o Grunt. Você pode conferir essa matéria no link abaixo:
Conhecendo Grunt: O Task Runner em JavaScript
Quando foi lançado em 2012, o Grunt fez muito sucesso e começou a ser usado por muitos desenvolvedores. Contudo, no ano de 2013, o Gulp foi lançado e hoje ele é bem mais usado e conhecido, com a impressionante marca de aproximadamente 1.300.000 downloads por semana.
Neste artigo iremos falar sobre seus recursos, já focando em sua última versão, 4.0, e conseguiremos entender o motivo de ele ser tão usado. A verdade é que o Gulp é bem simples de implementar e mais rápido do que o Grunt. Além disso, o seu arquivo de configuração é menor. Tudo isso faz com que muitas pessoas optem por usar o Gulp.
Para conseguir realizar uma comparação entre essas duas ferramentas de automatização, vamos usar o mesmo projeto que criamos no artigo anterior, mas agora usaremos o Gulp.
Como instalar o Gulp?
O Gulp, assim como o Grunt, foi desenvolvido em JavaScript e é executado no Terminal. Por isso, iremos usar o Node.js mais uma vez. Lembrando que se você não possuir o Node, poderá conferir nosso vídeo no YouTube onde ensinamos a instalar essa ferramenta, clicando aqui.
Vamos agora instalar o Gulp através da linha de comando. Para isso, execute o seguinte no Terminal:
npm install gulp-cli -g
Com esse comando iremos instalar o CLI do Gulp em nosso computador de maneira global, tornando-o acessível em qualquer projeto.
Adicionando o Gulp ao Projeto
A estrutura de pastas será igual à do projeto em Grunt. Será necessário iniciar um projeto em Node neste diretório. Assim, vamos executar npm init -y em nosso Terminal.
O primeiro módulo que iremos instalar é o próprio Gulp. Iremos executar o seguinte comando:
npm install gulp --save-dev
O próximo passo será criar um arquivo chamado gulpfile.js em nosso diretório raiz. Iremos realizar o import do módulo do gulp com a linha de código a seguir:
const gulp = require('gulp');
Agora estamos prontos para desenvolver nossos exemplos. Talvez você já tenha visto em alguma documentação ou tutorial sobre o gulp.task(), responsável por criar uma tarefa no Gulp. Esse método ainda existe. Contudo, na versão 4.0, o modo de criar tarefas mudou um pouco. Agora é recomendado que criemos uma função que irá definir o que a tarefa irá realizar. Depois, devemos exportar essa função por meio do exports do Node com um identificador. E esse identificador será reconhecido como o nome da tarefa. Vamos criar um primeiro exemplo para entender isso melhor. Vamos criar a tarefa que irá unir todos os arquivos CSS em um só e depois irá minificá-lo.
Para essa primeira tarefa, vamos precisar de três módulos: 1) gulp-concat (responsável por juntar os arquivos), 2) gulp-cssmin (responsável por minificar os arquivos) e gulp-rename (responsável por mudar o nome dos arquivos, se desejarmos). Para instalar os três de uma vez só, vamos executar o seguinte comando:
npm install gulp-concat gulp-cssmin gulp-rename --save-dev
Para realizar o import deles no projeto, vamos usar o seguinte código:
const concat = require('gulp-concat');
const cssmin = require('gulp-cssmin');
const rename = require('gulp-rename');
Vamos criar nossa primeira função, que chamaremos de stylesMethod(). Ela possuirá a seguinte sintaxe:
function stylesMethod() {
return gulp.src("./assets/css/*.css")
.pipe(concat("all.css"))
.pipe(cssmin())
.pipe(rename({ suffix: ".min" }))
.pipe(gulp.dest("./dist"))
;
}
Explicando: nós usamos o método src() do módulo gulp para encontrar todos os nossos arquivos CSS dentro da pasta desejada. Usamos também o método pipe(), que está associado com um conceito muito interessante do Node.js que são os streams. Esse método é um dos grandes responsáveis pela excelente performance do Gulp.
Dentro de cada método pipe() nós executamos alguma função. Executamos o concat(), informando o nome do arquivo que será gerado após a concatenação, usamos o cssmin() para realizar a minificação desse mesmo arquivo, realizamos a chamada do rename() para adicionar o sufixo “.min” ao arquivo final e por fim usamos outro método do Gulp chamado .dest() para definir o diretório que desejamos que o arquivo final seja gravado. Apenas um detalhe: é muito importante que usemos o return nas funções, para que nenhum erro seja retornado no Terminal.
E nossa função já está pronta. Precisamos agora exportá-la como uma tarefa. Para isso, basta usar a seguinte linha de código no final do arquivo:
exports.styles = stylesMethod;
A tarefa se chamará styles. Para testá-la, basta executar o seguinte no Terminal:
gulp styles
Ao fazer isso, vemos o seguinte resultado:
A tarefa foi executada corretamente e sem erros. Se formos até a pasta dist, encontraremos o arquivo all.min.css, com o seguinte conteúdo:
Nosso arquivo foi corretamente minificado e concatenado, e a nossa tarefa ficou bem menor em comparação com o arquivo do Grunt. Bem mais simples, não concorda?
Vamos fazer o mesmo para os arquivos JavaScript. Nós iremos baixar apenas o módulo gulp-uglify para a minificação dos arquivos (poderíamos usar o gulp-jsmin também se desejássemos). Para realizar sua instalação, vamos executar o seguinte comando:
npm install gulp-uglify --save-dev
O import dele em nosso código ficará assim:
const uglify = require('gulp-uglify');
E iremos criar uma função chamada scriptsMethod(), que conterá a seguinte sintaxe:
function scriptsMethod() {
return gulp.src("./assets/js/*.js")
.pipe(concat("all.js"))
.pipe(uglify())
.pipe(rename({ suffix: ".min" }))
.pipe(gulp.dest("./dist"));
}
Note que pudemos reaproveitar os outros módulos que já havíamos instalado. Apenas o uglify() foi diferente. Para exportar essa função como uma tarefa, iremos usar o seguinte código:
exports.scripts = scriptsMethod;
Para testar essa tarefa, vamos executar gulp scripts em nosso Terminal. O resultado será o seguinte:
A tarefa executou corretamente, excelente! Se formos ao diretório dist, encontraremos o arquivo all.min.js, com o seguinte conteúdo:
É realmente mais prático usar o Gulp. Antes de continuarmos, vamos fazer apenas uma pequena refatoração. O módulo do Gulp é muito amplo. Assim, realizar o require de seu módulo completo pode deixar nosso projeto um pouco mais pesado. Uma alternativa para resolver essa questão é usar o recurso de Atribuição por Desestruturação (palavra difícil hein), que foi implementado na versão ES6 do JavaScript, ou EcmaScript2015. Essa atribuição consiste em realizarmos o require de apenas uma parte do módulo, usando chaves para isso. No caso do módulo do gulp, nós usamos dois métodos: src() e dest(). Para realizar a requisição de apenas esses dois recursos, vamos deixar a primeira linha do arquivo gulpfile.js assim:
const { src, dest } = require('gulp');
Dessa forma nosso código fica mais leve. E agora, ao invés de chamar gulp.src() ou gulp.dest(), iremos usar apenas o nome dos métodos, o que deixará nossas funções da seguinte maneira:
function stylesMethod() {
return src("./assets/css/*.css")
.pipe(concat("all.css"))
.pipe(cssmin())
.pipe(rename({ suffix: ".min" }))
.pipe(dest("./dist"));
}
function scriptsMethod() {
return src("./assets/js/*.js")
.pipe(concat("all.js"))
.pipe(uglify())
.pipe(rename({ suffix: ".min" }))
.pipe(dest("./dist"));
}
Você pode aprender mais sobre os recursos do EcmaScript2015, como também de todo o JavaScript em nosso Curso Completo de JavaScript, onde criamos sete projetos reais usando essa incrível linguagem.
Agora que realizamos essa pequena refatoração, vamos implementar o último módulo, o watch(). Diferentemente do Grunt, que precisamos baixar um módulo externo para essa tarefa, o Gulp possui um módulo próprio para isso. Para realizar o import dele em nosso projeto, basta adicionar o watch em nossa atribuição por desestruturação:
const { src, dest, watch } = require('gulp');
Vamos criar uma função que irá vigiar a alteração nos arquivos de nossos diretórios. Seu conteúdo será o seguinte:
function watchFiles() {
watch("./assets/css/*.css", stylesMethod);
watch("./assets/js/*.js", scriptsMethod)
;
}
Explicando: não é necessário definir o return para o método watch(). Nós o executamos duas vezes. O primeiro parâmetro desse método envolve informar os arquivos que devem ser “vigiados”, e o segundo parâmetro define a função que será executada quando os arquivos forem alterados.
Vamos exportar essa função como o método padrão do Gulp. Assim, ao executar apenas gulp no Terminal, já estaremos vigiando as alterações nos arquivos. Para realizar essa exportação, iremos definir a função na propriedade default do exports, com o seguinte código:
exports.default = watchFiles;
Agora, quando executamos gulp, vemos o seguinte resultado no Terminal
E, ao alterar qualquer arquivo JS ou CSS, veremos o seguinte:
Vemos que as tarefas são executadas e o Gulp continua vigiando as alterações para nós.
Conclusão
Por meio desses exemplos conseguimos entender os recursos do Gulp, junto com as novidades de sua versão 4.0. Percebemos que ele é realmente mais simples, mais legível e simples de implementar em nossos projetos. Além disso, ele é bem rápido. Se estiver na dúvida se deve usar ou não o Gulp, pode instalá-lo sem medo, ele é uma ferramenta sensacional!
Você pode encontrar os códigos desenvolvidos nesse artigo em nosso GitHub.
Se você gostou desse conteúdo, não deixe de compartilhar com outros, isso nos ajuda bastante. Teria algum outro assunto (linguagem, ferramenta, tutorial) que você gostaria de ler em nosso Blog? Você pode enviar suas sugestões clicando aqui.
Até o próximo artigo! :)