Blocos

Ultimamente tenho optado cada vez menos por utilizar SPA em pequenas aplicações ou mesmo em aplicações com Server Rendering, simplesmente pelo fato de que de se não for para prototipação rápida ou prova de conceito (ou mesmo nesses casos), sua arquitetura front-end deve ser emergente para evitar otimização prematura, como qualquer arquitetura, certo?

Se há uma parte da arquitetura que não pode ser deixada pra depois é a modularização, sem ela o código é repetido, confuso, macarrônico e super difícil de testar.

Ai é que o problema começa. Quais das um milhão de formas de modularizar eu uso? Module Pattern? AMD? CommonJS? Namespace Pattern?

Como é de se esperar código vanilla é mais fácil de modularizar, já que as novas features de modularização do ES6/7 estão já há algum tempo disponíveis através de transpilers como o BabelJS. Então isso resolve meu problema com poucas linhas de configuração e um package.json. Um exemplo pode ser visto abaixo (da própria doc do BabelJS):

Mas e os módulos que não são AMD ou CommonJS, como eu utilizo?

Foi ai que o Browserify me ganhou, com ele, além de ganhar módulos eu ganho bundle, transpiling e a infinidade de pacotes que existem para o Node.JS no NPM. E isso no front-end. Além disso tenho o shim um velho conhecido desde o RequireJS, que nos permite usar qualquer módulo mesmo não sendo AMD ou CommonJS.

Este é exatamente o objetivo de criação do Browserify, então vamos por a mão na massa.
Instalação

Bom, ele é um plugin NPM entao:

Você vai ver que no site oficial é instruída a instalação global, prefira usar módulos locais assim você garante integração a qualquer builder e/ou desenvolvedor :D.

Junto com o browserify, instalamos junto o pacote Bluebird do node.js (usado para gestão de promisses super performáticas) para ver sua mágica como dependência da aplicação.

Agora vamos configurar

Configuração

Adicione o seguinte comando a seção de scripts do seu packages.json para rodar de maneira local:

O browserify precisa de um arquivo raiz pra começar a ler a árvore de dependências, como uma árvore de dependências:

Representação de uma árvore de dependências

Representação de uma árvore de dependências

O que fizemos foi configurar index.js como essa raíz e main.js como o arquivo final de bundle.

Crie o arquivo index.js:

Ele está requisitando um módulo chamado dosomething, como no node.js.

Crie também um arquivo “doSomething.js“:

Este módulo exporta uma função com dois parâmetros e faz o uso do módulo nativo do node.js para realizar uma promessa.

Uso

Pronto! Agora se nós rodarmos o comando:

O bundle é realizado e temos um arquivo main.js com o código compilado e minificado.
Se adicionarmos à uma página HTML simples verá o console aparecendo 😀

e o console:

console.log no google chrome

console.log no google chrome

Mas e o meu pipeline de build? Uso grunt, gulp e não quero mudar!

Você pode usar esses plugins: gulp-browserify e grunt-browserify
Ainda é possível transpilar Typescript, ES6/7, Coffescript e até Handlebars no meio do bundle, mas isso é assunto pros próximos posts.

Só pra dar um gostinho, veja o mesmo código com ES6:

ou

Conclusão

Instalar e configurar o Browserify é simples e não traz quase nada de boilerplate. Além disso ele te induz a modularizar melhor a sua code base, facilitando até o refactoring enquanto testa. É simples, testável, e pra quem gosta de vanilla atende sem super-mega-features-de-bind-lentas-e-factories-que-nem-sempre-voce-precisa funcionalidades a mais por exemplo, o controle da orientação a objetos ainda está na tua mão.

Eu tenho gostado muito de utilizá-lo e para um cenário onde já tenho build-tool configurada, se encaixa perfeitamente, sendo, na minha opinião, melhor do que utilizar o Webpack que acaba atuando como build-tool também. Mas isso é assunto para os próximos posts.

Falarei sobre testes, watch e integrações com Browserify nos próximos posts. Espero que tenham gostado. Quero saber o que acham, se têm utilizado e quais suas glórias e dores com seu uso, deixe seu comentário!

Abraços e até mais!
Link da Demo
BabelJs
Browserify

Fabio Damasceno