Como Organizar Projetos Em React
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?
- etc…
Em outras palavras, começar um projeto é fácil, o dificil é organizá-lo e mantê-lo. Nesse post irei compartilhar a maneira como eu organizo meus projetos em React. A idéia 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 de seguí-las, concordá-las ou não).
Basicamente a estrutura da pasta src
é essa, ao longo do post 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 armezandos alguns css’s e javascript’s globais do projeto. Também é salvo as imagens seja o logo do cliente ou algum background
(se existir). Caso exisa 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 irá 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 á 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 multí idiomas, 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 (irei explicar mais para frente) diferente. Caso um componente seja utilizado apenas por uma feature X, o mesmo deve ser criado dentro da pasta dessa feature.
Nesse exemplo, cada componente possuí uma pasta por conta do Docz, sendo assim, todo componente tem um .js
e .mdx
, por isso, existe as sub pastas, para armazenar ambos os arquivos. Caso você não utilize o Docz, pode deixar os arquivos .js
dos componentes na raiz da pasta, porém, á 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
irá armazenar os componentes que são containers do projeto, em outras palavras, irá 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 exlusivos 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 referente 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 e 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 irão ser informados nas rotas e realiazarã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 wrap’s para os pages e cada page deve ter um container.
components
Caso a feature precise de um componente exlusivo, 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
possuí 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 irá estar disponível para todo o projeto. Evitando também a repetição de código.
tests
Todos os testes estão armezanados dentro da pasta __tests__
, isso para facilitar no dia á 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, eu 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, porque? 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 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 post mostrei como organizo os arquivos e pastas dos meus projetos feito com React, lembrando que a organização não é exclusiva dele e podem ser reaproveitadas com Angular e Vue por exemplo.
Se você gostou não deixe de comentar e caso queira pode estar assinando a newsletter para receber novidades por email.
Até a próxima.