Press enter to see results or esc to cancel.

O Visual Studio 2015 e a Modern Web

Nos últimos 5 anos nós passamos pela revolução dos smartphones, todo o poder de computação de uma máquina do ano 2000 está no nosso bolso. Mais importante ainda, está no bolso de muita gente que nem usava o computador. Por isso, um projeto Web já nasce com a preocupação de funcionar em dispositivos móveis. Isso não pode mais ser ignorado, e as ferramentas que você usa precisam ser capazes de atender às necessidades impostas por essas mudanças na mesma velocidade com que elas evoluem.

A Modern Web nada mais é que um termo para designar esse cenário de mudanças constantes e extremamente rápidas da Web, a necessidade de ter uma solução para múltiplos dispositivos, de tamanhos e capacidades diferentes, conectados através de internets móveis restringidas por planos de dados.

O problema no mundo do ASP.NET

Ferramentas que auxiliam na automatização e otimização de tarefas no servidor já são (e devem ser) muito utilizadas por desenvolvedores, então por que não trazer isso para as tarefas relacionadas às camadas do Client também? Essa prática já é bastante adotada por desenvolvedores front-end, mas na comunidade .NET ela ainda é muito tímida. Apenas no MVC4 é que começou-se a esboçar um maior suporte com o Bundling e Minification, já o MVC5 trouxe o Bootstrap como tema padrão, são atualizações bem-vindas, mas que, além de terem parado por aí, sempre deixaram a sensação de estarem chegando atrasadas e não seguirem os padrões já adotado pelos desenvolvedores web.

Claro que você também pode analisar isso de maneira pessimista: mais ferramentas para aprender? Qual o problema de fazer tudo isso manualmente? Isso só pode ser mais uma invenção de desenvolvedores hipsters.

old man

Você não quer ser esse cara, né?

Visual Studio 2015

Mas afinal, qual o problema na maneira como desenvolvimento Web é tratado no Visual Studio hoje?
Em geral, o problema é que não existe muito suporte para ferramentas que têm se tornado padrão por desenvolvedores front-end do mundo todo: Bower, Grunt, Node e outras. Essas são algumas ferramentas que auxiliam a criação de soluções para Modern Web. Hoje algumas integrações são possíveis no VS somente através de plugins, e nem sempre o resultado é tão bom quanto a ferramenta original. As coisas também ficam escondidas demais, e nem sempre o desenvolvedor entende a razão e o que está acontecendo por trás dos panos. O maior avanço nessa questão tem sido através do Web Essentials, que é bastante focado nisso. Ele tem servido como um laboratório de aplicação das melhores práticas de front-end no ASP.NET, incorporando diversas funções a cada atualização do Visual Studio. No Visual Studio 2015 isso não será diferente.

Apesar do Web Essentials sanar algumas necessidades, ele ainda está longe de ser um perfeito substituto. Para resolver esse problema de vez, o Visual Studio 2015 mudou a forma de abordar o problema, agora o controle está todo nas suas mãos e você poderá utilizar a ferramenta que achar melhor, da mesma forma como desenvolvedores de todas as outras linguagens estão fazendo.

O Visual Studio ficou menos acoplado mas começou a tratar essas ferramentas como first-class citizens. Isso é muito importante, utilizando essas ferramentas você passará a compartilhar as mesmas práticas utilizadas pelos desenvolvedores de qualquer linguagem e não só de .NET. Isso significa maior documentação e atualizações mais rápidas pra você usufruir, e como bônus todas as ferramentas citadas a seguir são open source.

Seu cinto de utilidades

Basicamente a filosofia seguida é de não reinventar a roda. A ideia é ter mais ferramentas fazendo menos, ferramentas específicas que façam apenas uma coisa muito bem. É uma espécie de segregação de princípios aplicada em softwares.

Em geral, essa breve introdução serve para qualquer desenvolvedor interessado, independente da linguagem utilizada, no fim das contas você está executando os comandos puros de cada biblioteca, e pode utilizar o seu ambiente de desenvolvimento preferido.

Utilizei um projeto MVC 6 criado no Visual Studio 2015 CTP 6 como exemplo, caso queira ver o código-fonte, o projeto está no GitHub.

Node.js

node-logo

Tudo começa pelo Node.js. Em resumo, o node permite executar Javascript direto no servidor. Isso pode parecer meio estranho caso você nunca tenha lido sobre ele, mas é justamente isso que todas as ferramentas a seguir fazem, elas executam tarefas escritas em código JS. E por que Javascript? Bom, se você é desenvolvedor Web, o Javascript é a garantia de uma linguagem em comum para desenvolvedores do mundo todo, independente se você utiliza C#, PHP, Ruby ou qualquer outra linguagem web. Além disso, o node permite executar JS em qualquer sistema operacional, isso expande o alcance das ferramentas, sem restrições de sistemas operacionais nem de programadores, é fácil entender porque elas se popularizaram tanto.

O Visual Studio 2015 já vem com uma versão do Node instalada, mas ele permite trocá-lo por uma versão instalada por você quando quiser. O poder está sempre nas suas mãos.

npm

npm-logo

O npm é um gerenciador de pacotes para Javascript, ele é o ponto de partida para que você automatize seus processos. Seu uso é muito semelhante ao NuGet, instalando e restaurando pacotes do seu gigante acervo de pacotes. Lá tem de tudo, dá pra perder horas descobrindo novos pacotes. Ele também já vem instalado com o node e sua configuração é feita através de um arquivo package.json. É este arquivo que guarda todas as informações dos pacotes que você quer instalar através do npm. Veja um exemplo do arquivo que já é criado ao iniciar um novo projeto MVC 6:

    {
        "version": "1.0.0",
        "name": "ModernWebAspNet5",
        "devDependencies": {
            "grunt": "^0.4.5",
            "grunt-bower-task": "^0.4.0"
        }
    }

Sim, é tão simples quanto parece.

Bower

bower-logo

O Bower se denomina “um gerenciador de pacotes para Web”. E é isso que ele faz. Lá você encontrará bibliotecas CSS e também Javascript. Seu recurso mais interessante é que ele trata dependências de maneira “plana”, isso significa que caso duas bibliotecas A e B dependam de uma mesma biblioteca Y, ele baixará a biblioteca Y apenas uma vez. Você não precisa mais ter que baixar manualmente uma biblioteca javascript, nem ter que passar pelo pesadelo de ter que atualizar sua versão e suas dependências. O Bower faz tudo isso pra você.

O Bower também é facilmente configurado através de um arquivo bower.json, segue o exemplo utilizado por um novo projeto MVC 6:

{
    "name": "ModernWebAspNet5",
    "private": true,
    "dependencies": {
        "bootstrap": "~3.0.0",
        "jquery": "~1.10.2",
        "jquery-validation": "~1.11.1",
		"jquery-validation-unobtrusive": "~3.2.2"
    },
    "exportsOverride": {
        "bootstrap": {
            "js": "dist/js/*.*",
            "css": "dist/css/*.*",
            "fonts": "dist/fonts/*.*"
        },
        "jquery": {
            "js": "jquery.{js,min.js,min.map}"
        },
        "jquery-validation": {
            "": "jquery.validate.js"
        },
        "jquery-validation-unobtrusive": {
            "": "jquery.validate.unobtrusive.{js,min.js}"
        }
    }
}

NuGet x npm x Bower

Nesse momento você pode estar pensando: o NuGet, npm e Bower não fazem a mesma coisa? A resposta é sim e não. Calma, eu explico porque.

Sim, todas elas gerenciam pacotes, e você consegue usar o NuGet no lugar do Bower, ou o npm no lugar do Bower. Mas o NuGet não foi feito pra isso e isso é bem visível nas tentativas feitas pela comunidade. Existem algumas diferenças pontuais que tornam cada biblioteca a melhor escolha para uma determinada tarefa, este post faz uma boa análise a respeito das diferenças entre NuGet e Bower. Em resumo, a ideia de uma ferramenta fazendo apenas uma coisa prevalece.

  • NuGet: Otimizado para pacotes do servidor, instalar DLLs, adicionar arquivos com código C#, etc. Ex.: JSON.NET, EntityFramework.
  • npm: Otimizado para instalar ferramentas Javascript que podem rodar no node. Ex.: LESS, CoffeeScript, Grunt.
  • Bower: Gerencia e automatiza a instalação de pacotes da Web que serão distribuídos para o seu cliente (principalmente CSS e Javascript). Ex.: Bootstrap, JQuery, Angular.

Cada uma delas é muito boa no que ela se propõe a fazer, dividindo as responsabilidades você ganha muito mais poder e controle. Uma analogia que resume bem a necessidade dessas distinções: você pode quebrar uma parede com um martelo, mas existem ferramentas mais produtivas para isso.

Grunt e Gulp

grunt-gulp-logo

Por último, temos o Grunt e o Gulp, ambas são bibliotecas Javascript que rodam em cima do node e são utilizadas para automatizar tarefas. O próprio processo de instalação das dependências feito pelo Bower é um exemplo de tarefa que pode ser automatizada por elas.

Os projetos Web hoje podem ter diversas tarefas que devem ser executadas, muitas são executadas toda vez que um arquivo é alterado. Por exemplo: você pode estar utilizando LESS para gerar CSS, TypeScript para gerar Javascript, depois disso você minifica o seu CSS e seu Javascript e executa os testes de Javascript. É evidente que você se cansa de repetir essas tarefas bem rápido, o Grunt e o Gulp foram feitos justamente pra que você não tenha que interromper seu processo de desenvolvimento para executá-las.

Nos projetos MVC 6 o Grunt já vem pré-instalado, e sua configuração também é feita através de um único arquivo gruntfile.js:

module.exports = function (grunt) {
    grunt.initConfig({
        bower: {
            install: {
                options: {
                    targetDir: "wwwroot/lib",
                    layout: "byComponent",
                    cleanTargetDir: false,
                }
            }
        }
    });

    // Registra a tarefa com o alias "default", para instalação de todas as dependências 
    grunt.registerTask("default", ["bower:install"]);

    // Carrega o plugin
    // Importante: o carregamento do plugin deve sempre vir por último
    grunt.loadNpmTasks("grunt-bower-task");
};

Apesar de eu ter mostrado somente o Grunt neste exemplo, o Visual Studio dá suporte para o Gulp com as mesmas funções, fica a seu critério qual usar.

O Visual Studio tem Intellisense habilitado para os arquivos de configuração de todas essas ferramentas mostradas, você consegue ver quais pacotes estão disponíveis e suas versões. Também é possível restaurar e atualizar pacotes com um único clique, assim como você já está acostumado a fazer com o NuGet. Ainda assim, as saídas geradas pelas ferramentas estão sempre visíveis e você pode executar comandos manualmente sempre que quiser. Lembra quando eu disse que essas ferramentas estavam sendo tratadas como first-class citizens? É disso que eu estava falando.

Conclusão

O Visual Studio apenas está otimizando ainda mais o uso dessas ferramentas adicionando opções de menu para configurar e executar comandos, no fim das contas você pode atingir exatamente os mesmos resultados utilizando os utilitários de linha de comando de cada ferramenta.

As mudanças mais bruscas estão nos padrões do ASP.NET 5, que finalmente tornou mais fácil a adoção de padrões já utilizados por projetos de outras linguagens para permitir o uso dessas ferramentas. Isso não é surpresa sabendo que um dos objetivos do novo ASP.NET 5 é rodar no Mac ou Linux, no editor que você preferir. Isso significa que todas essas ferramentas podem ser usadas em projetos MVC 6 com o Sublime, Brackets ou qualquer outro editor que o OmniSharp já suporte.

Farei uma série de posts mostrando outras ferramentas que agora podemos utilizar no desenvolvimento de aplicações ASP.NET mais otimizadas para a Web. Desenvolvimento Web no ASP.NET não é mais uma caixa preta, e ela está cheia de possibilidades.

Imagens que ilustram o post: Bower, node.js, npm, Gulp e Grunt.

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInEmail this to someone
Comments

2 Comments

Rodrigo Milano

Interessante. Trabalho como Webdesigner há anos, mas sempre com Visual Studio. Então nunca usei Node, Bower, etc
Estou ainda aprendendo o que são e o que fazem. Seu artigo já ajudou muito.
Obrigado

Mahmoud Ali

Que ótimo Rodrigo, fico feliz em ter ajudado! 🙂


Leave a Comment