Tem ouvido muito falar em Gulp, Jade, Sass, Stylus, Less, YAML, EJS, etc, mas não sabe por onde começar? Seus problemas acabaram. Venha passear no território do workflow automatizado e vicie-se completamente.

Quem me iniciou no gulpjs foi o @fdaciuk, em uma palestra sobre gulp no WordCamp SP 2014. Hoje, tenho o prazer de apresentar pra vcs algumas dicas para começar JÁ a facilitar sua vida.

Neste artigo veremos o básico do GulpJS, e como trabalhar de forma automágica com pré-processadores (stylus e jade, mas é muito semelhante para usar com quaisquer outros que prefira)

(o resultado/exemplo está neste repositório do github)

Pré-Requisitos para Começar:

  • NodeJS

  • Gulp instalado globalmente:

Abra o terminal (com o nodejs já instalado) e rode:

1
npm install -g gulp

Isso deve deixar disponível o comando gulp no terminal.

Vamos começar?

Primeiro, crie uma pasta para seu projeto. Já deixe o console aberto nela também :P

Vamos criar o arquivo package.json, a base de todo projeto NodeJs.

[package.json][crie o arquivo na pasta de seu projeto]
1
2
3
4
5
6
7
8
9
10
{
"name": "gulp-primeiro",
"version": "1.0.0",
"devDependencies": {
"gulp": "^3.8.11",
"gulp-connect-multi": "^1.0.8",
"gulp-jade": "^0.11.0",
"gulp-stylus": "^2.0.0"
}
}

Note as devDependencies: gulp (este é o local, já instalamos o global, antes), gulp-connect-multi (servidor/livereload), gulp-jade e gulp-stylus.

Você acha pacotes maneiros de gulp, se precisar em npmjs.com, buscando por ‘gulp’ ou em GulpJS.com/plugins.

Com o console, rode:

1
npm install

Como criar uma task no GulpJs

Na pasta do seu projeto, crie um arquivo chamado gulpfile.js

[gulpfile.js]
1
2
3
4
5
var gulp = require('gulp');

gulp.task('teste', function(){
console.log("teste de task do GulpJS");
});

Salve e, no terminal execute:

1
gulp teste

Viu que bacana?

Saca a sintaxe: gulp.task(nome, função).

Usando Jade com Gulp Js

Ainda no gulpfile.js, ao final do arquivo, insira:

[gulpfile.js]
1
2
3
4
5
6
7
8
(...)
var jade = require('gulp-jade');

gulp.task('jade', function(){
gulp.src('src/jade/**/**.jade')
.pipe(jade())
.pipe(gulp.dest('build'));
});

Pontos importantes:

  • gulp.src() informa ao gulp qual arquivo ele vai usar, em formato de globs. 'src/jade/**/**.jade' significa todos arquivos .jade dentro de src/jade/ e subdiretórios.

  • .pipe() o pipe executa algo com o gulp.src(). Note como podemos usar vários .pipe() em sequência, e como não há ; até acabarmos.

  • jade() executa o módulo jade. Usado sempre dentro de um .pipe()

  • gulp.dest() após o .pipe(jade()), usamos o pipe(gulp.dest(nomeDaPasta)) para enviar o resultado para a pasta /build

Vamos criar um arquivo index.jade dentro da pasta /src/jade e testar logo nossa task ^_^y

[index.jade][Crie dentro da pasta jade]
1
2
3
4
5
6
doctype html
html(lang="pt_BR")
head
title= "Título da página"
body
h1 Teste de arquivo Jade!

Salve, abra o terminal na pasta raiz do projeto e rode:

1
gulp jade

Veja o resultado: Na pasta /build, que foi criada na raíz do projeto, há um arquivo index.html, que é o seu index.jade compilado.

Criando um server com LiveReload no Gulp JS

Vamos criar uma nova task, chamada de server. Ao final do gulpfile.js, insira:

[gulpfile.js]
1
2
3
4
5
6
7
8
9
(...)
var connect = require('gulp-connect-multi')();

gulp.task('server', connect.server({
root: ['build'],
port: 1337,
livereload: true,
open: { browser: 'chrome' }
}));

Pontos importantes:

Note que essa task não tem gulp.src, nem gulp.dest. O que fazemos é chamar connect.server(), com alguns parâmetros: root, port, livereload e open.

Agora salve o arquivo, e rode

1
gulp server

Maneiro né? Pra funcionar, você precisa ter executado a task jade antes. Podemos inseri-la como dependencia, mas faremos isso mais tarde.

Aperte ctrl+c no terminal para encerrar o servidor.

Usando Pré-processador CSS (Stylus) com Gulp Js

Criemos nossa task. Ela deve pegar os arquivos .stylus, gerar o css e salvar na pasta ./build

[gulpfile.js]
1
2
3
4
5
6
7
8
(...)
var stylus = require('gulp-stylus');

gulp.task('stylus', function(){
gulp.src('src/stylus/**/**.styl')
.pipe(stylus())
.pipe(gulp.dest('build/css'))
})

Crie uma pasta src/stylus e, dentro, um arquivo main.styl

insira:

[main.styl][crie dentro da pasta stylus]
1
2
3
4
5
6
$bgcolor = red;
$maincolor = blue;

body
background $bgcolor
color $maincolor

Salve, abra o terminal na pasta raíz e rode

1
gulp stylus

Yay!! Agora, dentro da pasta build/css temos o arquivo main.css, devidamente compilado do Stylus :D

Agora, não seria bacana se pudessemos deixar o servidor rodando e atualizar a página, compilar stylus e compilar jade sem ficar executando tasks o tempo todo?

SIM, SERIA MUITO LEGAL!

Usando LiveReload com GulpJs para atualizar quando houver alteração em algum arquivo

Pra isso, precisaremos de:

  1. task com funções .watch() pra cada tipo de arquivo (.jade e .styl)

  2. task que execute as tasks jade, stylus, server e watch, em sequencia

  3. inserir a função .reload() ao final de cada task

Então vamos lá:

1. Criando watch no gulp

Edite o arquivo gulpfile.js, inserindo ao final dele:

[gulpfile.js]
1
2
3
4
5
(...)
gulp.task('watch', function(){
gulp.watch(['src/jade/**/**.jade'], ['jade']);
gulp.watch(['src/stylus/**/**.styl'], ['stylus']);
})

Acima, usamos gulp.watch(), onde o primeiro parâmetro é um(alguns) GLOB(s) dos arquivos à serem monitorados e o segundo parâmetro, a(s) task(s) à executar

2. Criando uma task padrao para unificar tudo

Edite o arquivo gulpfile.js, inserindo ao final dele:

[gulpfile.js]
1
2
(...)
gulp.task('default', ['jade', 'stylus', 'server', 'watch']);

Se você cria uma task com o nome ‘default’, como acima, ela é chamada quando rodar o comando gulp pelo terminal.

Nesta, definimos que ela irá rodar as tasks jade, stylus, server e watch.

3. Inserindo reload() ao final das tasks jade e stylus

Editando o arquivo gulpfile.js, deixaremos as 2 tasks assim:

Task jade

[gulpfile.js]
1
2
3
4
5
6
7
8
(...)
gulp.task('jade', function(){
gulp.src('src/jade/**/**.jade')
.pipe(jade())
.pipe(gulp.dest('build'))
.pipe(connect.reload()); //linha adicionada
});
(...)

Task stylus

[gulpfile.js]
1
2
3
4
5
6
gulp.task('stylus', function(){
gulp.src('src/stylus/**/**.styl')
.pipe(stylus())
.pipe(gulp.dest('build/css'))
.pipe(connect.reload()); //linha adicionada
})

Ok, vamos ver que legal!
Rode, no terminal

1
gulp

Deve abrir seu navegador, com a página sem estilos.

Deixe rodando a task, e vamos editar o arquivo index.jade.

Deixe a janela do navegador com o conteúdo visível atraz do seu editor

Vamos inserir uma linha logo abaixo de title= "Título da página"

[index.jade][insira linha abaixo da title....]
1
2
title= "Título da página"
link(href='css/main.css', rel='stylesheet')

Salve o arquivo e…. tcharãaaa, veja como atualizou sozinha sua página. Experimente editar o main.styl, mudando as cores das variáveis por exemplo (de blue para white), e salve.

Seja bem vindo ao GulpJs. Automate all the things o/

(o resultado/exemplo está neste repositório do github)

Ah! Vale lembrar que, pra facilitar, declaramos os require logo antes de cada task.

O ideal mesmo é que sejam declarados todos ao começo do arquivo.

Ficaria mais ou menos assim, ó:

[exemplo de gulpfile.js]
1
2
3
4
var gulp = require('gulp')
, jade = require('gulp-jade')
, stylus = require('gulp-stylus')
, connect = require('gulp-connect-multi')();

Desafio/Lição de casa

Este desafio é só pra quem teve a primeira experiência com o GulpJs neste post, hein. Se você já manja, não adianta ;P

Note que nosso gulpfile faz:

  • Processa e gera html de arquivos jade
  • processa e gera css de arquivos styl

massss… falta uma task para lidar com os arquivos não processados (imagens, por exemplo).

O desafio/tarefa de casa é criar uma task E um watch para os arquivos não processados. Essa task deve apenas copiar eles para a pasta build e chamar o connect.reload() ao final.

dica: insira arquivos dentro de alguma pasta, como src/assets

No próximo post de GulpJS….

No próximo post de GulpJS veremos tarefas úteis para JS (que não abordamos aqui) e outras tarefas de otimização para distribuir seu projeto.

Gostou? Entendeu? Curtiu? Usou? Deixe seu comentário!!

Dúvidas?