Ecossistema React: etapas iniciais no setup de um projeto

Artigo dedicado a orientar os novos viajantes do ecossistema nas definições de estrutura e da stack

Rafael Maruta
React Brasil
Published in
13 min readFeb 22, 2018

--

Parte do ecossistema React e além!

Olá galera! Tudo jóia? Espero que sim =D

No meu artigo anterior (clique aqui para ver) comentei sobre os temas que os iniciantes em React devem se informar. Este artigo é uma continuação, ou um complemento. Agora vamos para um assunto mais prático, que são algumas pré-definições na arquitetura de um projeto.

Este artigo não contempla:

  • Razões para se usar React no projeto. Considerarei que já foi feita uma análise e decidido que React atende aos requisitos do projeto;
  • Server Side Rendering. Considerarei que o servidor já possui os requisitos necessários para rodar o projeto, com as respectivas APIs;
  • Aprofundamento em determinada tecnologia. No máximo um breve comentário;
  • Plugins para necessidades muito específicas. Como plugin para gráficos, manipulação de datas, drag and drop etc.;
  • Testes automatizados. Pois é um universo independente, mereceria um artigo próprio. Caso tenham curiosidade, recomendo que dêem uma olhada no lindo Cypress;
  • GraphQL. É um assunto extenso e também merece um artigo só para ele. Caso queiram saber mais, clique aqui;

Desde a definição da stack até a estrutura de pastas e arquivos, quais tópicos acabarão surgindo? A seguir eu levantei 15 tópicos que surgem comumente no momento da definição da stack de um projeto, com algumas breves recomendações.

1. Gerenciamento de dependências

Você poderia optar por usar estaticamente as dependências do React importando-as em seu HTML, mas se o seu projeto crescer e precisar de mais dependências, pode ser complicado fazer o controle e a manutenção de todas elas. Para um projeto evoluir sustentavelmente foram criadas algumas tecnologias que auxiliam em seu gerenciamento.

Em diversos casos é inviável criar uma solução do zero que já tem pronta e é estável, mantida por diversos bons desenvolvedores. Para gerenciar diversas dependências simultaneamente foram criadas soluções como o npm, que é um gerenciador de pacotes, onde ele baixa e instala o pacote de dependências definido em um arquivo package.json, disponibilizando-as para você usá-las em seu projeto.

Imagem de https://medium.com/learnwithrahul/is-it-really-worth-switching-to-yarn-from-npm-27781afcb7e5

Devido a alguns problemas do npm, o Facebook lançou uma ferramenta chamada Yarn, que também é um gerenciador de pacotes, que prometeu ser mais rápido e mais seguro, adotando recursos como a verificação de integridade das dependências, paralelismo na instalação, garantia de uso de uma mesma versão que funcione em diversos sistemas. Ele é altamente adotado pela comunidade.

Recomendo a consulta do site oficial pois a maioria dos artigos estão defasados, pois o npm passou por diversas melhorias principalmente com as atualizações do Node.js, principalmente com relação à performance.

Para quem pretende migrar, segue um link útil com uma tabela de relação de comandos entre npm e Yarn:

2. Usar um boilerplate ou configurar do zero

A seguir, ao se dar conta com a quantidade de dependências e configurações necessárias e tempo gasto configurando a base do projeto, você pode se deparar com tal questão:

Usar um boilerplate ou instalar e configurar tudo do zero?

Um boilerplate é um pacote de dependências e configurações que podem ser instalados rodando poucos comandos, com muito menos trabalho do que realizar tudo do zero. Também pode ser configurável e extensível.

Conforme o projeto vai crescendo, novas necessidades vão surgindo, e estas podem não serem atendidas pelo boilerplate. Para instalar algo novo em algo já pronto pode ser mais difícil do que se o projeto tivesse sido todo configurado do zero, ou até inviável. Um projeto configurado do zero, apesar de mais trabalhoso no começo, mais para frente pode se mostrar mais vantajoso, pois oferece mais liberdade.

Para projetos menores não vejo problema em usar um Create React App ou um Next.js (este que é bem completo e configurável), mas para projetos grandes e com potencial de crescimento recomendo uma configuração do zero. Caso você opte por um boilerplate, seguem alguns links úteis:

3. Configurando do zero, definindo um module bundler

Antes tínhamos as task runners, que ficavam em modo de watch acompanhando quando salvávamos nossas alterações de código, compilando-o para uma versão final adaptada para a renderização no navegador. Com a evolução dos projetos web, mais complexos eles se tornaram e mais tarefas e dependências se tornaram necessárias, então surgiram os module bundlers. Além de task runners, eles gerenciam componentes, módulos, validam código, unem, splitam em partes (chunks) para serem carregadas sob demanda, etc. garantindo a sustentabilidade da aplicação.

Uma imagem sobre o que é o Webpack ilustra bem o que são module bundlers

Citarei 3 module bundlers com suas respectivas recomendações:

Há um servidor para auxílio de desenvolvimento local criado para o Webpack, o Webpack Dev Server, mas deve ser instalado e configurado independentemente.

4. Linters

Para garantir a qualidade do código do projeto existem os linters, que no Webpack rodam como pré-loaders, que verificam a integridade do código que os desenvolvedores estão escrevendo antes de compilá-lo. Eles conseguem identificar determinados erros no código que farão sua aplicação quebrar antes mesmo de você rodar e testar no navegador, agilizando e automatizando o seu trabalho.

Além de testar a integridade do código, eles podem testar a qualidade e o padrão do código. Quando diversos desenvolvedores estão atuando no mesmo projeto, é importante que o código possua uma única identidade para ficar mais fácil que todos compreendam. Para resolver isto há o Code Styling, que é um conjunto de regras com boas práticas.

Há o Prettier, que é uma extensão de editores de código que formata o seu código automaticamente de acordo com as regras que você define. É possível configurá-lo para ele usar as regras do Standard. Está fazendo muito sucesso!

5. Transpiladores

Só por usar React com JSX você precisará usar um transpilador. Transpiladores servem para converter o código que você escreve em um código interpretável para o navegador. JSX precisa ser convertido em funções JavaScript. O transpilador mais conhecido e usado é o Babel, que transpila não só JSX, mas códigos com features mais recentes do JavaScript em uma versão que navegadores mais antigos também consigam interpretar. Transpila até features candidatas que ainda não foram aprovadas pelo comitê oficial TC39, permitindo que você as use antes mesmo de serem oficializadas!

Segue um link falando sobre o release mais atual do Babel, o Babel 7, como instalar e como usar:

6. Framework de testes

Como um bom dev você provavelmente vai querer seguir as recomendadíssimas boas práticas do TDD (Test Driven Development). É possível rodar os testes no terminal para que eles rodem com mais velocidade através de test runners, que inclusive podem ficar em modo watch para acompanhar as suas alterações enquanto escreve os testes. Você pode escolher uma lib de asserções de testes. Decidir também usar uma lib que mostra o coverage dos seus testes. Você precisaria instalar cada uma dessas libs como dependência do seu projeto, ou pode instalar um framework de testes que já vem como um pacote de praticamente tudo o que você precisará. É o caso do Jest, que é o framework mais usado pela comunidade do React. Ele já vem com um task runner, usa o Jasmine para asserções, o Istambul para coverage etc., além de ser fácil de instalar, configurar e usar. Segue o site oficial:

7. Testando componentes

É possível fazer snapshots dos componentes para verificar se algo que não deveria mudar nele mudou, mas se precisar de testes mais específicos e avançados, a lib mais conhecida e usada chama-se Enzyme (by Airbnb). É possível fazer testes nos componentes para verificação de valores fazendo seletores semelhantes à API DOM e o jQuery. Dê uma conferida:

No mundo dos testes é possível deixar nossas asserções mais amigáveis, de melhor leitura através da prática do BDD (Behavior Driven Development). É possível usar libs como o Chai nas asserções, e para o Enzyme há o Chai Enzyme:

É possível catalogar os seus componentes para manter um registro visual e de suas variações de estados, além de servir de plataforma para poder desenvolver isoladamente seus componentes, garantindo que eles sejam totalmente desacoplados. É o Storybook!

Outro catalogador de componentes que achei bem interessante e vale uma conferida é o BlueKit.

8. Tipagem estática

Tipagem estática também é uma espécie de teste, pois ele verifica os tipos em tempo de desenvolvimento, reduzindo a quantidade de bugs e cobrindo boa parte do caminho infeliz do TDD. Tanto o TypeScript quanto o Flow são boas adoções com o React.

Seguem algumas boas referências do Flow:

9. Estilos visuais

No mundo do React normalmente há dois caminhos a seguir: PostCSS ou CSS in JS. Ambos possuem vantagens e desvantagens, como por exemplo, muitos são contra a escrever CSS com JavaScript, sendo que há pré-processadores poderosos que possibilitam escrever lógicas que atendem às suas necessidades, como o Less, Sass e Stylus. Fora que o código fica isolado num arquivo externo que pode ser cacheado. Não tenho nada a discordar sobre, mas algo que é real é que a adoção de CSS in JS só tem crescido na comunidade.

Caso decida usar PostCSS, é possível adotar um recurso que se chama CSS Modules, onde o Webpack é capaz de buildar a sua aplicação inserindo uma hash no final das classes para evitar conflito entre elas, encapsulando melhor o seu componente.

Se for usar CSS Modules, recomendo o uso deste Babel Plugin React CSS Modules pois ele performa melhor no momento do build e dispensa o uso de decorators:

Mesmo com estas facilidades, assim como eu falei no artigo anterior, não abra mão da arquitetura de CSS, mesmo que seja só pela organização de código:

10. CSS in JS

Quanto ao CSS in JS, vou citar alguns benefícios que eu já senti por experiência própria:

  • Muitas vezes o estilo precisa ser dinâmico com o componente, e como o componente é em JavaScript, se o estilo também está em JavaScript, fica mais lógico e fácil de fazer esta interação;
  • A quantidade de código que você escreve e do build final podem ficar menor do que se fosse com PostCSS, portanto o esforço gasto também deverá ser menor;
  • Criação de componentes de estilos, que além de reutilizáveis, aceitam props.

Claro que há desvantagens também, como não poder gerar um arquivo externo para cachear, apesar de poder cachear o HTML gerado numa camada de cache e com Server Side Render. Não gostaria muito de alongar esta comparação pois não é o objetivo do artigo, prefiro que você pesquise e decida por si mesmo qual é o ideal para o seu projeto:

11. Estrutura de pastas e arquivos

A facilidade de componentização do React abre muitas possibilidades de organização, mas quando a liberdade é alta, o risco de desorganização também aumenta, principalmente conforme o projeto vai crescendo. Pensar em uma maneira de organizar seus componentes, módulos, helpers etc. mantendo de uma forma sustentável pode ser difícil, mas já existem algumas boas recomendações. Eu particularmente gosto muito do Atomic Design:

Eu só acabei substituindo os nomes:

  • Atoms = Elements
  • Molecules = Components
  • Organisms = Wrappers
  • Templates = Wrappers
  • Pages = Modules

12. Tratamento de rotas

Desenvolvendo uma SPA (Single Page Application) você precisará lidar com rotas, que são endpoints que carregam determinada parte, ou estado da aplicação e exibem no navegador. O mais usado é o React Router, que é uma lib de componentes que torna a sua aplicação navegável, possibilitando bookmarkable URLs, navegação pelo histórico etc.

13. Catálogo de componentes

Em uma aplicação grande e diversificada pode ser muito trabalhoso e custoso desenvolver componente por componente, por isso há diversas libs com bons e variados componentes mantidos pela comunidade. Desde buttons, selects, date pickers, range pickers etc., eles possuem um belo visual, seguindo um bom styleguide e se encaixam bem em diversos visuais.

Os últimos tops do GitHub são:

  • Material-UI: baseado no Material Design do Google:
    - http://www.material-ui.com/
  • Ant Design: belo e vasto catálogo de componentes com ricas funcionalidades embutidas. Formulários com componentes e validações avançadas e personalizáveis:
    - https://ant.design/

14. Máquina de estados

Para lidar com estados da aplicação não é em todo caso que o React resolve bem apenas com o state local dos componentes. Para situações complexas temos as máquinas de estados, que usam determinados patterns e arquiteturas para resolver estes problemas. Já escrevi um artigo sobre Redux, que usa a arquitetura Flux:

À esquerda é o problema, à direita é a solução proposta pelas máquinas de estados

Segue um artigo do Dan Abramov (criador do Redux) falando sobre a necessidade ou não de aplicação do Redux:

O Redux trabalha com dados imutáveis, ou seja, nunca se alteram, apenas evoluem. Para lidar com imutabilidade de dados grandes e/ou complexos, o Facebook criou o Immutable.js, que é uma lib que trata esses dados com uma implementação simples e focada em gerenciar bem a memória:

O ecossistema do Redux também é extenso pois temos os Middlewares que interceptam o retorno das Action Creators, possibilitando que elas realizem diferentes ações e retornem diferentes tipos de dados. Como por exemplo, temos:

Pela vastidão do ecossistema e sua complexidade, vários devs optaram por outros caminhos, como por exemplo o MobX, que garante ter uma implementação mais simples, fácil e performática:

Uma alternativa à máquina de estados, temos o ReactiveX, que resolve a questão usando o Observer Pattern.

Lembrando que caso opte por usar GraphQL com Relay ou Apollo, eles já possuem uma máquina de estados própria embutida, algo que facilita demais.

15. Lib de formulários

Lidar com formulários no React é complicado, principalmente se forem formulários grandes ou muito dinâmicos. O Ant Design possui seus recursos de validação, mas você pode acabar ficando preso à sua lib de componentes. Se você criar os seus próprios componentes de input ou quiser usar outra lib de componentes, pode ser interessante usar outra lib que lide com a lógica de formulários. O Redux Form teve uma adoção forte pela comunidade, mas o próprio Dan Abramov recomendou o não uso de Redux em formulários. Uma poderosa lib que lida com formulários muito adotada e bem aceita é o Formik.

Imagem de https://keyholesoftware.com/2017/10/23/the-joy-of-forms-with-react-and-formik/

Também temos agora o novíssimo Final Form, do Erik Rasmussen, criador do Redux Form, que resolveu alguns problemas como a dependência do Redux e a exclusividade do React, ou seja, é totalmente agnóstica. Para usar com React é necessário usar uma dependência extra, o React Final Form.

Conclusão

Mesmo tentando ser breve o artigo acabou ficando um pouco extenso, mas creio que consegui abranger muitos casos que com certeza você vai se deparar. Só para reforçar: não se limite aos tópicos e artigos que postei aqui, ele é só um ponto de partida para que você saiba o que deve considerar no momento da definição de um projeto com React. Continue sendo sempre curioso e pesquisando. Sempre estão surgindo soluções novas e melhores. Estudos deverão constantes!

Sei que é bastante coisa e juntar tudo em um projeto pode ser complicado, até porque é comum acontecerem conflitos entre dependências e aí é preciso encontrar uma solução, que nem sempre é fácil de descobrir ou de se encontrar. Eu criei um boilerplate onde praticamente todos os possíveis problemas estão resolvidos. Ele foi configurado totalmente do zero, portanto é totalmente customizável. Segue o link:

Fique a vontade para fazer fork, ou se ao usar você encontrar algum problema, pode abrir uma Issue, ou mesmo um Pull Request. Mesmo que não queira usá-lo, você pode analisá-lo para descobrir como eu resolvi algum determinado problema que você pode ter encontrado. Caso haja algo que eu possa não ter resolvido ainda, pode também abrir uma Issue.

Para finalizar: caso queira citar mais tópicos, ou complementar, sinta-se a vontade nos comentários!

Valeu e até mais! o/

--

--