Front End

21 fev, 2019

Como organizar projetos em React

Publicidade

Começar um projeto React hoje é fácil, mas e mantê-lo? Será que é só rodar um create-react-app? Na maioria dos projetos o problema acaba sendo a organização. Dúvidas do tipo:

  • Quais pastas criar?
  • Onde criar meus componentes?
  • Como separar os arquivos?
  • Onde tal arquivo deve estar?

Em outras palavras, começar um projeto é fácil. O difícil é organizá-lo e mantê-lo. Nesse artigo irei compartilhar a maneira como eu organizo meus projetos em React.

A ideia não é dizer que minha organização é a melhor ou a bala de prata para todos os seus problemas, mas dar sugestões e dicas (fique à vontade para segui-las, concordar com elas, ou não).

Basicamente a estrutura da pasta src é essa. Ao longo do artigo irei explicar cada pasta e o motivo delas.

mocks

A pasta __mocks__ é responsável por armazenar os mocks para a execução dos testes com Jest.

_assets

Na pasta _assets são armazenados alguns CSSs e JavaScripts globais do projeto. Também são salvas as imagens, seja o logo do cliente ou algum background (se existir).

Caso exista a necessidade de fontes ou ícones personalizados, eles também ficam na pasta _assets.

_config

A pasta _config, como o próprio nome já diz, é responsável por realizar configurações no projeto, por exemplo:

  • config.js: responsável por verificar qual ambiente está rodando e retornar suas configurações. Podemos usá-las, por exemplo: config.api.url, que terá um valor respectivo para cada ambiente
  • history.js: criação e configuração do browser history ou hash history
  • http: criação e configuração do objeto axios. Depois pode ser usado: http.get, abstraindo qual biblioteca está sendo utilizada para realizar as requisições
  • reducers: configuração e junção de todos os reducers do projeto
  • routes: configuração e junção de todas as rotas do projeto
  • sagas: configuração e junção de todos os sagas do projeto
  • scripts: toda importação referente a arquivos .js
  • store: configuração da store global do Redux
  • style: toda importação referente à arquivos .css

_environments

A pasta _environments é responsável por armazenar informações e configurações que diferenciam de um ambiente para o outro. Por exemplo, a URL da API.

As configurações de ambiente que estiverem nesses arquivos não devem ser informações sensíveis. Se por um acaso existir algum token ou api key, elas devem ser setadas através do dotenv e configuradas como variáveis de ambiente.

Assim conseguimos em boa parte dos casos dar uma segurança maior ao projeto, pois as informações não estarão inclusas no bundle .js final e sendo trafegada pela rede, surgindo a necessidade de hackear a máquina para ter acesso a tais variáveis.

_translate

Na pasta _translate é feita toda configuração de internacionalização e multi-idioma. Nela, existe uma pasta filha chamada languages, que para cada idioma terá um .js responsável pelas traduções.

components

A pasta components como o próprio nome também diz, é responsável por armazenar todos os componentes do projeto. Porém, existe um pequeno detalhe: os componentes localizados nessa pasta devem ser “globais”.

Ou seja, utilizados em pelo menos duas features (explicarei mais para adiante) diferente. Caso um componente seja utilizado apenas por uma feature X, o mesmo deve ser criado dentro da pasta dessa feature.

Neste exemplo, cada componente possui uma pasta por conta do Docz. Sendo assim, todo componente tem um .js e .mdx, por isso existem as sub pastas para armazenar ambos os arquivos.

Caso não utilize o Docz, pode deixar os arquivos .js dos componentes na raiz da pasta, porém, a partir do momento que o componente X não possuir apenas um arquivo, uma sub pasta deve ser criada.

constants

A pasta constants armazena valores que são utilizados em vários lugares dos códigos, assim, caso algum valor um dia precise mudar ou ser atualizado, essa mudança e atualização será feita em apenas um lugar.

containers

A pasta containers armazenará os componentes que são containers do projeto. Em outras palavras, armazenará os componentes que fazem o wrap da aplicação.

features

A pasta features irá armazenar e separar os contextos (alguns chamam de domínio) do projeto, por exemplo: client, product, home, login, dashboard, etc.

Cada pasta feature deve possuir todos os arquivos responsáveis, necessários e exclusivos da feature – podemos ver, por exemplo, a feature de produto:

Repare que dentro dela estão todas as informações do produto. Exemplo:

  • actions.js: ações disparadas pelo Redux
  • api.js: chamadas para a API
  • constants.js: constantes exclusivas da feature (geralmente o type das ações)
  • Product.js: modelo que representa o produto
  • reducers.js: todos os reducers do produto
  • routes.js: todas as rotas referentes ao produto
  • sagas.js: todos as sagas do produto
  • selectors.js: todos seletores do produto. Esses seletores serão os responsáveis por buscar informações na store
  • Mapear para o componente
  • store.js: informações da store do produto

Além desses arquivos, normalmente também teremos mais duas pastas dentro de cada feature, sendo elas containers e pages:

pages

Dentro da pasta pages estará o componente que será renderizado na tela.

containers

Dentro da pasta containers estarão os componentes burros que serão informados nas rotas e realizarão o mapeando das ações e store (mapDispatchToProps e mapStateToProps) para os componentes da pasta pages.

A ideia de não chamar diretamente os componentes da pasta pages é para facilitar futuramente nos testes, facilitando a necessidade de mockar ações, stores, etc.

Os containers basicamente serão wraps para os pages e cada page deve ter um container.

components

Caso a feature precise de um componente exclusivo, uma pasta components deve ser criada para armazená-lo. Se um dia ele for necessário e compartilhado em mais de uma feature, o mesmo deve ser migrado para a pasta components da raiz (src/components).

A ideia é parecida com a especificidade do Editorconfig ou ESLint. Quanto mais baixo for o nível da pasta, mais específica e exclusiva ela será.

helpers

A pasta helpers possui valores e auxiliares para trabalhar com styled-components.

utils

A pasta utils possui funções que serão reaproveitadas e utilizadas em várias partes dos códigos. Assim, a manutenção fica mais fácil, pois ao realizar a modificação em um determinado arquivo, a mesma estará disponível para todo o projeto. Evitando também a repetição de código.

tests

Todos os testes estão armazenados dentro da pasta __tests__. Isso para facilitar no dia a dia, pois geralmente eles são bem menos modificados do que os demais componentes.

Assim, se tivermos os arquivos .test.js soltos pelas pastas, ele estarão visualmente poluindo-a. Se eu quero mexer com um teste, eu vou na pasta de teste, não preciso ficar vendo eles a todo momento.

Saiba mais

Você provavelmente deve estar curioso porque algumas pastas possuem o “_” na frente, sendo elas:

  • _assets
  • _config
  • _environments
  • _translate

Afinal, por que? O motivo é para que elas fiquem separadas das demais pastas. Então, adicionando o “_” elas ficaram juntas no topo do diretório e também para dar a ideia de pastas “privadas”, ou seja, que não devem ser acessadas diretamente através de import.

Também faço essa organização em projetos Angular e Vue, algumas modificações (normalmente pequenas) são necessárias por conta de cada arquitetura, mas, de uma forma geral, quase tudo é organizado do mesmo jeito.

Conclusão

Nesse artigo mostrei como organizo os arquivos e pastas dos meus projetos feitos com React.

Lembrando que a organização não é exclusiva dele e pode ser reaproveitada com Angular e Vue, por exemplo.

Se você gostou, não deixe de comentar.

Até a próxima!