Gulp. Orquestrador em JavaScript

Pode parecer fácil criar um blog, site ou e-commerce se pensarmos que tudo pode ser resumido em apenas três partes: um arquivo HTML, para a montagem dos elementos na tela; um arquivo CSS, que funcionará como central de estilos para os elementos; e um arquivo JS, para especificar como cada elemento se comportará em determinados eventos.

No início dos web sites, o conceito de desenvolvimento web baseava-se na criação desses três simples arquivos que, com pouco tempo de desenvolvimento, já tomavam a forma de um site. Mas, devido ao avanço das tecnologias e consequente aumento do fluxo de navegação, essa tríade se tornou cada vez mais complexa — precisando de maior quantidade de arquivos e linhas.

Isso incentivou a criação de inúmeras ferramentas que se propõem a facilitar o desenvolvimento e a manutenção desses sistemas. Uma destas ferramentas — simples, mas poderosa — é o Gulp.

Gulp

Gulp é uma ferramenta JavaScript em forma de módulo NPM que permite orquestrar tarefas baseando-se no conceito de correnteza. Para entender esta ideia, imagine que as várias tarefas se encontram num rio — a correnteza leva os dados de uma tarefa para outra, de forma que o resultado é sempre passado para a próxima. Essa é a concepção de I/O, in and out.

Cada tarefa deve ser realizada de forma simples, com um único objetivo, uma única transformação. Este processo de modularizar tarefas torna o Gulp uma ferramenta muito poderosa em termos de reutilização de código e simplicidade de leitura.

Para compreender o Gulp basta conhecer cinco funções que ele oferece. Mas antes disso vamos falar do que é um glob e como algumas das tarefas que veremos a seguir utilizam este conceito.

Um glob pode ser entendido como uma lista de arquivos que seguem um determinado padrão. Esta lista pode ter um ou mais arquivos e o padrão corresponde a um caminho no sistema operacional. Para ser um arquivo só, basta referenciar o glob com a string do caminho deste arquivo, como por exemplo ./src/index.js. Mas para referenciar mais de um arquivo é possível utilizar o caractere ‘*’ no seu caminho, como por exemplo ./src/**/*.js. Este caminho irá referenciar todos os arquivos com a extensão .js dentro da pasta ./src e dentro de seus pastas filhas.

Aqui na Touch Health, utilizamos o Gulp para controlar vários tipos de tarefas como compilar arquivos JavaScript para browsers incompatíveis com as novas funcionalidades do ECMAScript 6, para compilar arquivos que utilizam a linguagem React, ou até mesmo para unificar muitos arquivos em um só. É possível também fazer tarefas simples como deletar arquivos, sincronizar arquivos de uma pasta a outra, ou até mesmo lançar notificações no desktop do usuário.

Sem mais delongas, vamos às funções que o Gulp nos possibilita utilizar.

gulp.task(nome, fn)
Cria uma tarefa com um nome específico e, quando chamada, realiza a função correspondente.

gulp.run(tasks…)
Roda várias tarefas com o máximo de simultaneidade possível.

gulp.watch(glob, fn)
Observa um glob e, sempre que há mudança em algum arquivo correspondente a este glob (adição, modificação ou remoção), realiza a função correspondente.

gulp.src(glob)
Emite arquivos que correspondem ao glob para uma próxima tarefa, arquivo por arquivo.

gulp.dest(destino)
Arquivos que chegam a esta função são salvos no destino especificado.

E é isso! O Gulp se resume ao que foi explicado acima, mas caso queira “colocar a mão na massa” e entender como ele funciona, continuaremos com um passo a passo de uma aplicação básica para compreender todas funções explicadas e um pouco mais.

Para seguir com o artigo, é necessário ter instalado em seu computador o NPM e o Node.js. Caso não tenha e queira instalar, acesse o site oficial do Node para instalar ambos: Site oficial do Node.JS
A parte prática deste artigo é destinada a usuários de sistemas operacionais baseados em UNIX, como Linux e MacOS.

GulpInit — orquestrando tarefas

Em primeiro lugar, precisamos montar nosso projeto. Recomenda-se criar uma pasta para cada projeto, assim, sempre teremos uma referência e linguagem única. Neste artigo, a pasta raiz será a pasta Developer.

Como já temos o NPM e o Node instalados e atualizados, podemos instalar o Gulp e suas ferramentas de linha de comando.

npm install -g gulp

Em seguida, criaremos nosso projeto com o nome gulpInit. Neste projeto usaremos dependências NPM e para isso precisamos de um package.json para controlarmos quais dependências instalamos no nosso projeto.

mkdir gulpInit && cd mkdir gulpInit
npm init -y

Após criarmos nosso ambiente de desenvolvimento, precisamos indicar que utilizaremos o Gulp em nosso projeto, mas em escopo de desenvolvimento, pois não há a necessidade de compilarmos códigos do Gulp para nossos clientes.

npm install gulp — save-dev
npm ls gulp

Se tudo for feito corretamente, ao rodarmos npm ls gulp veremos que o nosso projeto instalou corretamente o Gulp em sua última versão disponível.

gulpInit@1.0.0
└── gulp@3.9.1

Para confirmar, podemos observar nosso package.json e verificar que ele foi criado corretamente:

Agora, basta adicionarmos um arquivo chamado gulpfile.js ao nosso projeto. Este é o arquivo lido pela ferramenta Gulp e que armazena todas as tarefas a serem orquestradas.

Para criar o arquivo, utilize o comando:

touch gulpfile.js

Abra o arquivo em seu editor de texto favorito e copie o seguinte código:

var gulp = require(‘gulp’);

Como você pode ver, existem quatro áreas dentro de um arquivo Gulp: dependências, variáveis, funções e tarefas. É sempre bom ter estas áreas em mente para manter um código limpo e de fácil leitura.
Nosso Gulp irá orquestrar uma tarefa simples: todos os arquivos JavaScripts que estão dentro da nossa pasta src serão copiados para a pasta lib.

Para isso, é necessário primeiro criar um arquivo simples dentro da pasta ./src.

./src/script1.js

console.log(‘Este é o meu primeiro arquivo JS’);

Agora começa a parte interessante — criar tasks e funções no nosso gulpfile.js. A primeira função que criaremos copia todos os nossos arquivos JS para uma pasta de destino que chamaremos de lib.

As funções Gulp que utilizaremos são gulp.src e gulp.dest, mas note que pelo menos mais duas funções são executadas no arquivo a seguir. Observe e tente apontar quais são.

Conseguiu verificar? Bem, as funções que dissemos que utilizaríamos, src e dest, se encontram na função copiaArquivos. Mas você notou uma função pipe que não foi citada anteriormente? Esta é a função que, codificadamente, explicita o conceito de correnteza. Podemos olhar o Gulp também como um conjunto de canos, de forma que cada cano é uma tarefa e o comando pipe() junta cada um dos canos.

Correnteza ou canos, temos nosso primeiro arquivo Gulp funcional. Mas, antes de testarmos, lembra que falamos que mais duas funções estavam sendo registradas neste arquivo? Uma é óbvia: estamos falando da função gulp.task.
Dentro da área de tarefas temos uma função task que cria uma tarefa default e atribui a ela uma função correspondente, neste caso, essa função simplesmente chama a função de copiar arquivos.

Todo arquivo gulpfile.js deve conter pelo menos uma função default, que será chamada toda vez que o comando gulp for chamado sem nenhum parâmetro.

A outra função que está sendo usada neste arquivo é a gulp.run – que é utilizada mesmo que não esteja escrita em nenhum lugar. Basta pensarmos no que ela faz e concluímos que é o próprio gulp que a utiliza por debaixo dos panos.

Ao rodarmos o comando gulp no nosso terminal, além de alguns processos internos, o Gulp faz a seguinte chamada:

gulp.run([‘default’])

Esta chamada faz com que o Gulp realize a tarefa default, que consequentemente chamará a função correspondente a esta tarefa. Então, quando rodamos o gulp no nosso terminal, é possível observar que foi criada no nosso projeto uma pasta ./lib com um arquivo script1.js.

Pronto, nosso Gulp funciona! Ainda falta utilizar a tarefa watch, mas para isso podemos avançar nosso gulpfile.js para um nível maior, mais sofisticado.

Foi dito que o gulp.task cria uma tarefa e associa uma função a ela, mas ele não faz somente isso. Na verdade a tarefa task associa outras tarefas à tarefa criada e, ao terminar o fluxo de tarefas, realiza a função determinada pela tarefa original. Uma possível utilização seria a seguinte:

gulp.task(‘original’, [‘tarefa1’, ‘tarefa2’, ‘tarefa3’], function(){
 console.log(‘Terminei minhas tarefas’)
})

O que irá acontecer neste cenário é que serão realizadas as tarefas: tarefa1, tarefa2, tarefa3, nesta ordem, e depois será realizada a função que imprime no console a string ‘Terminei minhas tarefas’.

Podemos modularizar mais nosso gulpfile.js da seguinte forma:

Desta forma, modularizamos a função de copiar arquivos para uma task própria. Portanto se chamarmos gulp no nosso terminal, ou gulp copiaArquivos, ambas chamadas realizarão a tarefa copiaArquivos.

Para finalizar, usaremos a função watch para verificar sempre que houver alguma mudança em qualquer arquivo JavaScript do nosso glob de entrada. Para isso, criaremos uma nova tarefa chamada watch-copiaArquivos que ficará observando esse glob e, quando houver mudança, chamará a tarefa copiaArquivos novamente.

Esperamos que tenha entendido como o fluxo da orquestração do Gulp funciona. Mas isto não para por aqui! Existem centenas de plugins que podem ser usados juntamente com o Gulp para facilitar o processo do seu sistema: SASS, browserify, minify, entre muitos outros. Para encontrar estes e mais plugins, basta entrar no site oficial do NPM. Este site oferece algumas formas de procurar plugins, mas atente-se sempre para os plugins mais utilizados, que são listados logo na página inicial.

E caso você queira criar um plugin para Gulp, o site do Gulp tem tutoriais específicos para isso, assim como muitas outras informações que não pudemos explicar aqui.

Esperamos tê-lo ajudado a compreender como é possível orquestrar diversas tarefas e a melhorar o fluxo de tarefas em seu ambiente de trabalho ou em projetos pessoais. Caso você já utilize o Gulp, deixe seu comentário contando um pouco de sua experiência. Se pretende utilizar, volte para compartilhar sua opinião e como este artigo o ajudou.

Gostou? Não se esqueça de Recomendar e Compartilhar!