JavaScript sem padrões: não é bem assim
Antes de explicar do que se trata este post, me sinto na necessidade de falar do que não se trata este post. Este não é um post sobre se você deve usar ponto-e-vírgula (para este assunto você pode ver aqui, aqui, aqui, aqui, aqui, aqui, aqui, aqui ou aq… chega, né?). Este post também não é sobre qual framework MVC/MVP/MVVC/Flux/CQRS você deve usar (mas espere para ver uma pincelada não-polêmica sobre assunto no final do post).
Mas espera, se não é sobre isso, sobre o que é este post?
Bom, a ideia do post começou na minha cabeça quando surgiram os posts “The sad state of <alguma coisa relacionada a JavaScript>” e “<Alguma coisa relacionada a JavaScript> fatigue”. E teve seu ápice quando li o post State of the Art in JavaScript in 2016 e com o caso npm vs Azer vs kik. Mais especificamente com a discussão em volta do que com a remoção do módulo left-pad.
Com todo o alarde gerado sobre o JavaScript não ter esta função no core, ou não ter uma biblioteca oficial que contenha este tipo de função, com a impressão das pessoas de que o JavaScript não tem bibliotecas básicas padrão (mesmo as que não fazem sentido serem parte do core, mas que sejam a primeira opção na hora de resolver um dado problema) senti a necessidade de escrever um post que mostrasse que a comunidade JavaScript tem sim bibliotecas padrão assim. E é sobre isto que este post vai falar. Você pode enxergar este post como uma espécie de awesome, porém mais descritivo e com foco apenas nas ferramentas mais usadas de cada categoria.
Funções básicas
Dado que um dos estopins para este post foi a confusão por causa do left-pad
, acho válido que esta seja a primeira categoria. Nesta categoria há duas opções:
- lodash: Se você não tem preferência por algum estilo de programação específico (você entederá o porque de eu dizer isto no bullet abaixo), simplesmente opte pelo
lodash
. Ele terá a maioria das funções que você precisa, e se você ainda está confuso sobre usarlodash
ouunderscore
, leia esta issue. - Ramda: Mas se você quer algo mais funcional, vá de Ramda. Me desculpe pessoal do lodash/fp, mas o Ramda sai na frente. Se quiser saber o porque, leia a sessão “What’s different?” do site do Ramda.
Servidor e autenticação
Esta é uma das poucas categorias dentro do universo JavaScript que não há tantas opções (perceba que aqui não incluo frameworks para aplicações, mas sim algo mais baixo nível).
- Express: O Express é, de longe, o microframework para criação de servidores mais usado da comunidade do Node. Mesmo com toda a confusão recente envolvendo o Douglas Wilson, esta ainda é a melhor opção. A comunidade que produz bibliotecas que funcionam com Express é bem maior que a do Hapi e do Restify, e se você precisar de algo ainda mais baixo nível, opte pelo Connect.
- Passport: Se você precisa adicionar autenticação à sua aplicação Node, Passport é a melhor opção. Com dezenas das chamadas “estratégias” de autenticação, incluindo autenticação com Facebook, Twitter, OAuth, JWT e vários outros, o Passport é a opção mais completa.
Promises e programação assíncrona
Programação assíncrona é um dos grandes fortes do JavaScript, seja usando Promises ou não. Porém, como o gerenciamento manual de código assíncrono é difícil e o surgimento de Promises na especificação linguagem é recente, ainda é necessário usar bibliotecas que facilitam o uso de código assíncrono, veja as melhores opções a se usar para este tipo de problema:
- async: Se você vai trabalhar com código assíncrono sem usar promises, nem perca tempo procurando outras opções, escolha o
async
. Esta foi uma das primeiras bibliotecas grandes à resolver o problema com código assíncronos e atualmente já tem mais de 800 mil downloads diários (números tirados do próprio NPM). - Bluebird: É a biblioteca de promises mais performática atualmente, sendo até 100 vezes mais rápida que sua concorrente Q, que também não é uma má opção se você vai usar promises no browser. Para o caso geral ou quando estiver em dúvida, opte pelo
Bluebird
.
CLI
Com o surgimento de frameworks e aplicações não-web construídas com Node, criar uma CLI se tornou um fator bem importante, com dezenas e dezenas de opções à se escolher, seguem as principais:
- Inquirer: Se você precisa fazer uma CLI bastante interativa, com perguntas, checkboxes, listas e tudo mais, sua melhor opção será usar o Inquirer. Esta é, inclusive, a biblioteca usada que adiciona toda aquela interação ao yo.
- minimist: Mas se você que algo mais baixo nível, apenas para parse dos argumentos passados por linha de comando, escolha o
minimist
. Se você esteve na comunidade Node desde o início você deve se lembrar do optimist, que foi descontinuado em favor do yargs. Sendo assim, usar ominimist
ou oyargs
torna-se apenas questão de preferência pela API. Na dúvida prefira ominimist
por ser mais usado, com cerca de 700 mil downloads diários.
Logging e debug
Debugar aplicações Node de maneira prática nunca foi uma tarefa muito fácil, mas já há opções muito boas. Quanto à logging, este “setor” da comunidade JavaScript foi, por muito tempo, dominado pelo Winston, que hoje em dia está longe de ser a opção devido a altíssima quantidade de bugs presentes no mesmo. Saiba então o que usar:
- debug: Apesar do nome, o
debug
é uma biblioteca de logging bem minimalista que pode ser configurada facilmente e ativada/desativada com o uso de variáveis de ambiente. Precisou de uma biblioteca de logging básica: use odebug
. Realmente precisa de algo mais elaborado? Use o log4js. - morgan: O
morgan
é um logger de requisições HTTP extretamente útil, e que tem em seu núcleo o própriodebug
, citado acima. - node-inspector: O Node Inspector é hoje a mais usada estratégia de debug usada em aplicações Node, com uma configuração um pouco mais complicada que a sua concorrente mas que vale a pena de se usar. Uma alternativa ao Node Inspector seria o ironNode, que apesar de ainda ser pouco usado vem crescendo bastante dentro da comunidade. Na dúvida, opte pelo
Node Inspector
.
Envio de emails
- nodemailer: Aqui não há dúvidas: precisou enviar emails em uma aplicação Node, use o
Nodemailer
. Com plugins para os serviços de email mais populares do mercado oNodemailer
é a opção mais completa para este tipo de tarefa.
Banco de dados
Nesta categoria vou apresentar duas opções para casos bem distintos mas que são, claramente, as melhores opções para cada um dos dois casos:
- sequelize: Se sua aplicação precisa se conectar com um banco de dados SQL (Postgres, MySQL, MariaDB, SQLite ou Microsoft SQL Server), opte pelo
Sequelize
. Dentre todas as opções de ORMs para Node (e há muitas), oSequelize
se sobresai por ter uma das melhores documentações, além de uma CLI bastante completa, com suporte à migrations e generators. - mongoose: Este é um outro caso onde não há discussão: se sua aplicação vai se conectar a MongoDB, simplesmente use o
Mongoose
. É a opção mais usada e com a comunidade mais ativa para quem usa MongoDB com Node.
Testes e cobertura
Esta é uma daquelas partes meio polêmicas, onde é necessário tomar cuidado para não ser opinado demais, vamos lá:
- mocha: O
Mocha
é o framework de testes mais usado na comunidade do JavaScript. Você não deve usar somente ele para seus testes (veja os próximos bullets), mas se não sabe bem por onde começar com testes em JavaScript, esta será sua melhor opção, principalmente levando-se em conta a comundiade deste módulo. - chai: O
Chai
é uma biblioteca de asserção que pode ser usada perfeitamente em conjunto com oMocha
. Com a opção de usar o estilo TDD ou BDD de escrita de testes. - sinon: Já o
Sinon
é uma biblioteca que facilita o uso de spys e stubs em testes JavaScript. Você pode estar pensando que usar o Jasmine é uma melhor opção do que usar o combo Mocha + Chai + Sinon, mas posso afirmar que, após um certo tempo trabalhando com o Jasmine, você começa a tropeçar em problemas que simplesmente não existiriam se você usasse estas três bibliotecas. - enzyme: Se a sua aplicação é feita com React e você pretende (e eu espero que pretenda) testar seus componentes, simplesmente use o Enzyme. Com uma API extremamente mais simples que a do React Test Utilities, o
Enzyme
, do pessoal do AirbBnB, será sua melhor opção. Quer um motivo? Eu aposto que você prefere procurar um elemento renderizado com a classemy-class
usandocomponent.find('.my-class')
(com o Enzyme) do que comReactTestUtils.findRenderedDOMComponentWithClass('my-class')
(com o React Test Utilities), não é mesmo? - supertest: Precisa fazer testes com requisições HTTP? Use o
supertest
. Ele usa internamente osuperagent
e permite criar testes com HTTP com uma sintaxe simples e idiomática. - factory-girl: Se você veio da comunidade Ruby, uma coisa que você pode ter sentido falta na hora de escrever testes que usam o banco de dados é uma boa biblioteca de factory. Com o
factory-girl
este problema acaba. Com uma API bastante prática e vários adapters para ORMs, ofactory-girl
é a melhor opção caso você precise testar usando o banco de dados. - istanbul: O Istanbul é o módulo mais usado e completo de geração de code coverage para Node. Se precisar gerar coverage do seu código, não tenha dúvida, use o Istanbul.
Você pode estar se perguntando “Mas e o tape? E o AVA?”. Bom, eu não me esqueci deles, mas dado que eles possuem problemas para rodar testes no navegador, por exemplo (que facilitaria o debug em casos de erro), preferi não adicionar eles à lista.
Sockets
Sockets são também um dos grandes pontos fortes do Node na hora de desenvolver uma aplicação web em tempo real. Mas qual biblioteca escolher?
- primus: Para começar com o pé direito quando for trabalhar com sockets no Node, use o Primus. Ele é uma abstração que te permite usar diversas bibliotecas de socket de maneira genérica. Daí em diante vira só uma questão de foco da sua aplicação para escolher qual biblioteca usar.
- socket.io: Usando como adapter do Primus ou não, o
Socket.IO
é a biblioteca de socket mais usada pela comunidade do Node. Na dúvida, escolha oSocket.IO
, dada a quantidade de features e aplicações grandes que o usa. - sockjs: Mas se você quer uma biblioteca com menos features mas mais performática, você pode optar por usar o
SockJS
, que não tem, por exemplo, suporte à salas mas aguenta mais requisições simultâneas sem ferir a performance do seu servidor.
Data
Trabalhar com datas em JavaScript é uma outra tarefa que, por muito tempo, foi uma coisa chata, mas há um certo tempo temos um vencedor na hora de resolver este problema:
- moment: Se você precisa trabalhar com datas, efetuar operações com elas e tudo mais, não pense duas vezes e use o
Moment
. - moment-timezone: Se, além de trabalhar com datas você precisa trabalhar com timezones, você pode usar este plugin para o
Moment
chamadoMoment Timezone
, e seus problemas estarão resolvidos.
Imutabilidade e programação reativa
O título desta seção é composto por dois termos que estão bastante em foco na comunidade JavaScript atual. Mais quais bibliotecas usar?
- immutable: Se sua aplicação precisará usar dados imutáveis, escolha o
ImmutableJS
. Produzido pelo pessoal do Facebook, oImmutableJS
possui uma ótima documentação, super completa, além da própria biblioteca ser completíssima. - rxjs: Vindo da família de Reactive Extensions, que possui implementações para várias linguagens, o RxJS é hoje a biblioteca para programação reativa mais em foco na comunidade JavaScript, principalmente por ser usado internamente em um framework front-end que não vou me atrever a citar ainda.
Lint
Após anos tendo esta parte do “mercado” JavaScript dominado pelo JSLint e o JSHint, a comunidade JavaScript finalmente ganhou uma nova opção, renovada e que não sofre dos bugs que seus antecessores sofriam:
- eslint: O
ESLint
é a melhor opção atualmente para linting de código JavaScript, inclusive com suporte completo à ES2015/ES6, além de plugins para suportar regras específicas do JSX.
Bundling e compilação
Esta é uma outra parte polêmica dentro da comunidade JavaScript, principalmente quando o assunto é bundling. Perceba agora que é tudo uma questão de necessidade:
- babel: Nesta parte não há muito dúvida. Precisou compilar código ES6+ para JavaScript que os browsers atuais entendem: escolha o Babel. Outras opções como o traceur, do Google, não tem uma comunidade nem minimamente tão ativa quanto a do Babel.
- browserify / webpack: E aqui começa a polêmica. E agora,
browserify
ouwebpack
? É apenas uma questão de necessidade, e eu falo sério. Você precisa apenas traduzir CommonJS/ES Modules de modo que o navegador entenda, semrequire
s dinâmicos, só com JavaScript (usando, ou não, o Babel) de uma maneira prática e rápida de configurar? Não pense muito, escolha obrowserify
. Quer algo mais elaborado, que compile também para outros padrões de módulos (como AMD, por exemplo), compilar CSS junto, com uma flexibilidade maior, code splitting e tudo mais, ao custo de ter bem mais trabalho configurando? Use owebpack
. É só isso.
A polêmica
Eu disse no começo do post que eu passaria rapidamente e sem muita polêmica pelo assunto frameworks.
Eu não vou te falar aqui que React é melhor do que Angular ou Ember (apesar de, pessoalmente, eu preferir o React), ou que o CycleJS é melhor porque é mais funcional e reativo, mas vou citar aqui coisas que, ao meu ver, dominaram esta fatia do mercado JavaScript:
- DOM Virtual: independentemente se é usando React, o Ember que possui o Glimmer, o virtual-dom ou o CycleJS, que usa o
virtual-dom
internamente, a tendência do uso de DOM virtual para minimizar as alterações no DOM “de verdade” do navegador é notável. Eu diria que, independente do que você vá escolher como framework, prefira um que use DOM Virtual. (Nota: estou sendo bem pessoal aqui) - Eventos: A “era” de comunicação direta entre componentes UI, que acarretava em partes da tela não serem atualizadas, acabou. Com o surgimento de arquiteturas como o Flux e o crescimento da programação funcional e reativa (ou FRP), adotado pelo CycleJS por exemplo, que permite a notificação de toda a UI sobre modificações e atualizações da tela, este tipo de problema já está basicamente resolvido, tornando-se apenas uma questão de opinião e gosto pela API na hora de escolher qual framework usar.
Eu sei que o post ficou longo, mas espero ter conseguido alcançar o objetivo de mostrar que o JavaScript tem bibliotecas padrão e reconhecidas, basta você saber pra onde olhar.