Skip to content

Aprenda a utilizar o Gulp no Visual Studio para fazer sua vida mais fácil

Hoje vamos falar sobre o Gulp no Visual Studio. Gulp é um task runner e com ele a vida do desenvolvedor torna-se mais fácil.

Para aqueles que já estão acostumados com a plataforma .Net, versão 4.0 e 4.5, sabem que para minificar arquivos js, css e outros, basta utilizar o Bundle. O Bundle é algo fantástico e muito utilizado, mas eu vejo uma desvantagem, é apenas utilizado por quem desenvolve em .Net.

Sua melhoria e extensão fica restrito a própria comunidade. Alguém pode criticar o meu argumento, nem acho um argumento tão forte, mas por que não podemos utilizar coisas que outras comunidades utilizam e melhoram a todo instante para somar com a nossa plataforma?

É nisso que a Microsoft vem apostando com a sua nova pilha de desenvolvimento. A Microsoft a partir do Visual Studio 2015 e o novo ASP.NET decide dar a liberdade para a utilização do Node, Bower (Fiz um artigo sobre Node e Bower) e Gulp, algo que não foi desenvolvido pela Microsoft, mas sim pela comunidade Node.js e que já está bem difundida em outras plataformas. O assunto de hoje é sobre o Gulp, o que é e como utilizar ele em nossos projetos. Através dele vamos aprender a criar tarefas e a integrar essas tarefas no build do Visual Studio. Bora começar!

Algumas vezes tenho o pensamento que desenvolver softwares não é uma coisa difícil, focar apenas no código e ouvindo música é uma coisa prazerosa. Mas desenvolvimento não é só isso, desenvolver é cuidar de outras partes que muitas vezes são chatas e dolorosas, aí nesse momento eu já mudo de ideia e percebo que programação não é tão fácil assim. Você já teve esse pensamento? Por exemplo, você cria um sistema do zero, seja ele uma ideia sua ou aplicação que alguém está lhe pagando para desenvolver.

O começo parece lindo, segue todos os manifestos que você conhece. Mas quando vai chegando perto da publicação você percebe uma porrada de coisas que ainda falta fazer para dar certo, não estou falando necessariamente de funcionalidades do sistema, mas sim de coisas mais pequenas, tarefas que precisam ser repetidas a cada publicação. Uma dessas tarefas está relacionada com a performance do site, por exemplo: diminuir o tamanho dos js e css é uma tarefa, comprimir o html é outra tarefa, validar se os js não tem erro é outra tarefa. Coloquei alguns exemplos apenas.

No desenvolvimento de um site existe muitas tarefas que são repetitivas como expliquei já mais acima e o Gulp pode automatizar essas tarefas. Em seu site, gulpjs.com, ele se descreve como “automatizar e melhorar seu workflow”. Gulp foi criado pela comunidade Node.js e ele sozinho quase não faz nada, pois ele precisa de plug-ins que auxilia na tarefa desejada. Por exemplo, quer minificar um arquivo? Tem um plug-in especifico para isso. Quer validar se existem erros no js? Tem outro plug-in especifico para isso também.

Cada plug-in tem uma responsabilidade especifica (Igual aos métodos que fazemos no trabalho :)). A filosofia do Gulp é simples, configurar as tarefas através do seu próprio código e assim deixar as tarefas simples e mais divertidas. A configuração do Gulp em projetos ASP.NET Core é zero, isso por que ele já vem instalado e configurado. Já em projetos legados, deve fazer alguns passos que irei demonstrar abaixo.

A primeira coisa é instalar o Node.js, caso tenha dúvida na instalação leia um outro artigo que fiz sobre o assunto. Lembre-se, a Microsoft está investindo muito em Node.js, se você não conhece é bom a partir de agora começar a conhecer.

Após a instalação do Node.js, automaticamente será instalado o NPM. O objetivo do artigo não é este, mas em uma rápida explicação Node.js é uma plataforma de desenvolvimentoe o NPM é o seu gerenciador de pacotes para que não precisamos reinventar a roda. Entendeu? Com o NPM instalado vá no root do seu projeto e através de linha de comando digite: “NPM init”. Ao digitar este comando, ele fará algumas perguntas para ser inserido no arquivo criado. Instalado o Gulp? Não, claro que não! Este comando serve apenas para criamos um arquivo de configuração em nosso projeto, através dele iremos listar todos os pacotes node que iremos instalar através do NPM. Vá até o root do seu projeto e valide se o arquivo package.json foi criado com sucesso. Cuidado para não confundir com um outro arquivo package que existe mas em XML e utilizado pelo Nuget.

Depois volte para a linha de comando e digite: “NPM install gulp –save-dev”. Este comando irá instalar o Gulp em seu projeto e inserir sua dependência no arquivo que criamos mais acima. Agora temos o Gulp instalado, mas não configurado. Para isso, crie um arquivo no diretório raiz do seu projeto chamado “gulfile.js”. Este é o arquivo responsável por toda a configuração que iremos fazer em nosso projeto. Antes de escrever nossas tarefas, vou passar algumas estruturas do Gulp para melhor entendimento para quando formos praticar. Todos os métodos que temos em Gulp são: .task(), .src(), .watch(), .dest(), .parallel(), and pipe().

Task: Este é o método de entrada, através dele serão informados um nome e uma função que nada mais é do que o código que será executado para a tarefa.

Src: Através desse método escolhemos o arquivo ou arquivos que deverão ser modificados após a execução da tarefa.

Watch: Como o nome já fala, este é um método que fica assistindo determinados arquivos para que de forma automática execute alguma tarefa. Essa é uma das coisas que eu acho mais massa no Gulp.

Dest: Esse é o método que informa o destino onde o arquivo modificado residirá.

Pipe: Talvez o mais importante método aqui, através dele executamos todos os processos necessários da tarefa sem que tenhamos que esperar a finalização de cada processo e assim montar uma cadeia de processos na ordem que queremos.

Parallel and Series: Métodos utilizados caso você tenha que executar processos em paralelo.

Legal, você tem uma ideia do core do Gulp, agora podemos avançar a aprofundar sobre o assunto. No arquivo criado, chamado “gulpfile.js”, adicione o seguinte trecho de código e volte para a linha de comando e digite: “Gulp default”

[sourcecode language=”javascript”]

var gulp = require(‘gulp’ );

gulp.task(‘default’, function () {

console.log(‘hello world’);

});

[/sourcecode]

Se notar a resposta na linha de comando vai ver que ele imprimiu a mensagem que informamos no processo. Note também que para criar uma tarefa utilizamos o método task. Mas antes de criar uma tarefa, foi necessário carregar o pacote Gulp, para isso é necessário a utilização do método Require. Conforme eu falei mais acima, o Gulp sozinho não faz milagre, para aumentar o nível de nossas tarefas é necessário utilizar além do Gulp, outros pacotes com as suas especificas responsabilidades. Antes de utilizarmos outros pacotes, vamos criar uma aplicação básica no Visual Studio 2015 para que possamos trabalhar na melhoria desse projeto. A ideia é pegarmos o fonte já pronto e melhorar o css e js.

Irei começar os trabalhos com os css, se notar no código abaixo temos dois styles no layout da página. Minha ideia é concatenar os dois arquivos para transformar em apenas um, diminuir seu tamanho, retirando os espaços desnecessários e por último gerar apenas os styles que realmente são utilizados pela página, descartando coisas que estão no arquivo css mas não são utilizados, como exemplo o bootstrap.

[sourcecode language=”html”]
<link href=”/Content/bootstrap.css” rel =”stylesheet” />
<link href =”/Content/site.css” rel =”stylesheet” />
[/sourcecode]

Para fazer todos os processos descritos acima, é necessário instalar pacotes responsáveis por esse processo. Para isso vamos instalar os pacotes: gulp-concat, gulp-cssmin e gulp-uncss. Para instalar faça o mesmo processo na instalação do Gulp. Abaixo o código para criação das tarefas.

[sourcecode language=”javascript”]

var gulp = require(‘gulp’ );
var concat = require(‘gulp-concat’ );
var uncss = require(‘gulp-uncss’ );
var cssmin = require(&amp;quot;gulp-cssmin&amp;quot; );

gulp.task(‘css-concat’, function () {

return gulp.src([ ‘content/*.css’, ‘!content/*.min.css’ ])

.pipe(concat(‘site.min.css’))

.pipe(gulp.dest(‘content/’));

});

gulp.task(‘css’, [‘css-concat’], function () {

return gulp.src( ‘content/site.min.css’)

.pipe(uncss({

html: [ ‘http://localhost:64161/’]

}))

.pipe(cssmin())

.pipe(gulp.dest( ‘content/’));

});

[/sourcecode]

Vamos a uma a explicação. Você já viu antes como o Gulp é carregado, então, os outros pacotes também deverão ser carregados dessa forma. Após a declaração das variáveis, é a vez da criação das tarefas e aqui temos duas, uma para concatenar todos os arquivos que estão dentro da pasta “content” e outra tarefa para apenas gerar os styles utilizados pela aplicação. Observe que as duas tarefas estão relacionadas com a geração do css.

Na primeira tarefa ao carregar todo css da aplicação para concatenação, estamos excluindo o arquivo css que geramos no fim deste processo, neste caso o arquivo com final “min.css”. Eu excluo este arquivo colocando na frente um sinal de exclamação “!”. Lembre-se, toda tarefa Gulp sempre tem um arquivo de entrada e por isso estamos utilizando o método Src. No primeiro pipe temos a concatenação e como parâmetro o nome que será chamado o arquivo gerado. No segundo pipe estou enviando como parâmetro o destino do arquivo e por isso utilizo o método Dest. Note que em cada pipe utilizo um pacote que antes fizemos a instalação.

A segunda tarefa é parecida, exceto por alguns detalhes. O arquivo de entrada é o arquivo gerado na primeira tarefa. No primeiro pipe utilizamos o pacote uncss para comparar com o html passado como parâmetro quais styles estão sendo utilizados. Em vez de passar uma página, você pode passar a pasta onde estão os seus HTMLs. No segundo pipe utilizo o pacote cssmin para minificar o arquivo e no último pipe o destino para este arquivo, neste caso estou usando a mesma pasta. Uma diferença de estrutura entre a primeira tarefa e a segunda são os parâmetros. Na segunda tarefa é passado [‘css-concat’], que informa que esta tarefa deve ser executada antes, assim você não precise executar primeira uma e depois a outra.

Agora para ver o resultado basta voltar para linha de comando e digitar: “gulp css”. E os benefícios? Antes de criar a tarefa a aplicação tinha dois css de um total de 125k, agora temos um css com um total de 8k, ou seja, menos trafego entre muitos arquivos e tamanho.

Mas ainda não acabamos, vamos agora trabalhar com os js. Na página Layout.cshtml temos três arquivos js sendo utilizado. A tarefa a ser criada é concatenar e minificar para somente um arquivo.

[sourcecode language=”javascript”]
<script type=”text/javascript” src =”/Scripts/jquery-1.10.2.js”></script>
<script type =”text/javascript” src =”/Scripts/bootstrap.js”></script>
<script type =”text/javascript” src =”/Scripts/respond.js”></script>
[/sourcecode]

Segue o Gulp atualizado com as tarefas para geração do arquivo js.

[sourcecode language=”javascript”]

var gulp = require(‘gulp’ );
var concat = require(‘gulp-concat’ );
var uncss = require(‘gulp-uncss’ );
var cssmin = require(&amp;quot;gulp-cssmin&amp;quot; );
var uglify = require(‘gulp-uglify’ );

gulp.task(‘css-concat’, function () {

return gulp.src([ ‘content/*.css’, ‘!content/*.min.css’ ])

.pipe(concat(‘site.min.css’))

.pipe(gulp.dest(‘content/’));

});

gulp.task(‘css’, [‘css-concat’], function () {

return gulp.src( ‘content/site.min.css’)

.pipe(uncss({

html: [ ‘http://localhost:64161/’]

}))

.pipe(cssmin())

.pipe(gulp.dest( ‘content/’));

});

gulp.task(‘js’, function () {

return gulp.src([ ‘scripts/jquery-1.10.2.js’, ‘scripts/bootstrap.js’ , ‘scripts/respond.js’, ‘!scripts/site.min.js’ ])

.pipe(concat(‘site.min.js’))

.pipe(uglify())

.pipe(gulp.dest(‘scripts/’));

});

[/sourcecode]

Agora temos uma tarefa criada chamada “js”, a estrutura dela é a mesma, temos um ponto de entrada, ou seja, os arquivos que estão sendo utilizados na página e menos o arquivo que sempre é processado pelo Gulp. Depois efetuamos a concatenação e a sua distribuição na pasta. A diferença nessa tarefa é a utilização do pacote uglify, ele é responsável por minificar e validar a existência de erros nos arquivos js, caso encontre, finaliza a tarefa alertando o erro encontrado.

Voltando aos benefícios, nas duas imagens abaixo é possível ver o log do browser, uma imagem de antes e outra depois das alterações. É possível ver uma grande diferença tanto de tamanho de arquivo quanto tempo de download. Uma diferença entre utilizar o bundle do ASP.NET e o Gulp é a tarefa de gerar um arquivo css apenas pelo que as páginas estão utilizando, pois para quem já está acostumado a usar o bootstrap sabe que muita coisa não vai ser utilizado e isso vira um problema de performance, pois 90% não é utilizado.

gulp antes

gulp depois

Ok, otimizamos nossos arquivos e estamos prontos para publicação, mas e o desenvolvimento? Vou trabalhar com os arquivos concatenados e minificados? Claro que não, até por que fica difícil trabalhar assim em desenvolvimento caso você precise analisar o arquivo no firebug. Então, para isso podemos usar uma técnica que ajuda a diferenciar quais arquivos utilizamos em desenvolvimento e em release. Segue o código:

[sourcecode language=”csharp”]

@if(HttpContext.Current.IsDebuggingEnabled){

<link href=”/Content/bootstrap.css” rel =”stylesheet” />
<link href =”/Content/site.css” rel =”stylesheet” />

}

else{

<link href =”/Content/site.min.css” rel =”stylesheet” />

}

[/sourcecode]

Ao colocarmos esse código, o sistema trabalha de forma perfeita tanto para o desenvolvedor quanto para o ambiente de produção, e assim, não precisamos ficar alterando o código caso seja dev ou prod.

Mas ainda falta mais uma coisa, até agora trabalhamos com o Gulp de forma manual, para demonstração é legal, mas ter que ficar executando linha de comando toda vez que altera um arquivo já não é legal. Então, temos que preparar o Gulp para ser executado toda vez que a aplicação faz um build no sistema. Para isso, temos que construir mais uma task no Gulp conforme o código abaixo:

[sourcecode language=”javascript”]

gulp.task(‘build’, [‘css’, ‘js’], function () {

console.log(‘executing gulp build’);

});

[/sourcecode]

Essa task serve apenas para que através dela possa ser executado as outras task. Criada a task build agora podemos ir nas propriedades do projeto web no Visual Studio, Build Events e inserir o código abaixo:

cd $(ProjectDir)
gulp build

Agora, toda vez que a aplicação sofrer um build a task build irá ser executada e assim não precisamos mais executar a task do Gulp de forma manual. Note que outra diferença entre o Gulp e o Bundle do ASP.NET é que os arquivos são gerados antes da publicação, pois no modo do Bundle o arquivo é gerado na primeira requisição do sistema em produção.

Conclusão

Para quem está acostumado a desenvolver aplicações na plataforma .Net, também está acostumado a apenas usar auxiliares desenvolvidos pela Microsoft. O bundle do ASP.NET é um exemplo, é excelente e confiável. Mas creio que chegou o momento de enxergar coisas que funcionam fora comunidade .Net e que estejam dando certo e trazer para nossas aplicações em .Net. O Gulp já é um sucesso não só dentro da comunidade Node.js mas também em outras plataformas de desenvolvimento. Com o Gulp criamos tarefas e temos milhares de possibilidades para desenvolve-las e ajudar em nosso desenvolvimento, pois, o legal do desenvolvimento é desenvolver código e não perder tempo com tarefas rotineiras que podem ser automatizadas.

Espero que vocês tenham curtido mais esse artigo e até a próxima. Se gostou ou não, deixe um comentário. See you later!

Fontes

http://www.davepaquette.com/archive/2014/10/08/how-to-use-gulp-in-visual-studio.aspx
http://docs.asp.net/en/latest/client-side/using-gulp.html
https://www.smashingmagazine.com/2014/06/building-with-gulp/
http://tattoocoder.azurewebsites.net/using-gulp-for-asp-net-5-visual-studio-2015/

Published in.Net Core.Net Frameworknode.jsVisual Studio

Be First to Comment

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *