Seguir a estrutura de pasta proposta pelo Angular-cli é eficiente em pequenos projetos. Mas um desafio manter a coesão da estrutura para projetos que crescem em tamanho.
A estrutura proposta pelo cli
Ao iniciar um projeto Angular alguns comandos do angular-cli permitem criar novos componentes. O comando abaixo é utilizado para criar a maioria dos componentes
ng g component my-new-component
O resultado será uma nova pasta com quatro arquivos dentro:
|-- app
|-- my-new-component
|-- my-new-component.component .|html|scss|spec|.ts
|-- my-other-component
|-- my-other-component.component .|html|scss|spec|.ts
O cli possui também comandos para criar modules, directives, guard dentre outros.
O problema é que ao adicionar novos componentes, modules e services esta mesma estrutura será adotada. Manter todos no mesmo lugar é caminhar rumo ao fracasso. O site será difícil de manter, não será escalável, não haverá uma lógica compreensível entre a parte pública e privada. Não haverá uma clara distinção entre services, pipes e directives. Esta abordagem torna-se ainda mais complexa ao adicionar mocks, guard e filters.
Tão breve haverá um cenário caótico:
|-- app
|-- [+] component-a
|-- [+] component-b
|-- [+] interceptors
|-- [+] mocks
|-- [+] services
|-- [+] header
|-- [+] panel
|-- [+] directives
|-- [+] guard
|-- [+] home
|-- [+] login
|-- [+] pipe
O problema é a mistura desses componentes com todos os demais grupos de funcionalidades. Adicionar mais componentes deixa a Lógica mais confusa. É fácil perceber que a estrutura se torna obsoleta assim que o sistema crescer.
Por que estruturar as pastas do projeto Web?
Melhores práticas trazem benefícios concretos para a empresa. Seguir uma boa prática é como um atalho. Existem outros caminhos. Às vezes não sabemos o porquê do atalho. Mas seguir por ele aumenta as chances de sucesso. Os benefícios a longo prazo trazem ganhos na qualidade do software.
Escalabilidade
O código será mais simples escalar. Adicionar novos componentes, módulos e páginas não provoca inchaço as pastas existentes. Mantém a complexidade do sistema baixo. Logo a integração de novos desenvolvedores será uma tarefa tranquila. Além disso, com essa abordagem, é relativamente simples descartar recursos dentro e fora do aplicativo. Testar uma nova funcionalidade ou removê-la será fácil.
Debugar
Debugar o código será mais transparente com essa abordagem modularizada. Manter uma estrutura coesa traz benefícios para encontrar bugs e corrigi-los.
Um jeito diferente do cli
Não existem balas de prata ao tentar criar uma estrutura de pastas eficientes para Angular. Vai depender das funcionalidades e do tamanho do projeto. A estrutura vai mudar muito dependendo do projeto. Este artigo vai propor e explicar o cenário de um projeto estruturado em módulos. Com componentes e shared services.
A estrutura
Abaixo a estrutura proposta para projetos de grande porte
|-- modules
|-- module1
|-- [+] components
|-- module1.service.ts
|-- module1.module.ts
|-- module1.routes.ts
|-- module2
|-- [+] components
|-- module2.service.ts
|-- module2.module.ts
|-- module2.routes.ts
|-- shared
|-- [+] components
|-- [+] mocks
|-- [+] models
|-- [+] directives
|-- [+] pipes
|-- core
|-- [+] authentication
|-- [+] footer
|-- [+] guards
|-- [+] http
|-- [+] interceptors
|-- [+] mocks
|-- [+] services
|-- [+] header
|-- app.module.ts
|-- app.component.ts
Módulos - Lazy Load
Módulos lazy loaded ajudam a diminuir o tempo de inicialização da aplicação. Com o lazy load, o aplicativo não precisa carregar tudo de uma só vez. Ele só vai carregar o que o usuário espera ver. O módulo só irá carregar quando o usuário navegar para sua rota. Perfeito para aplicações grande, combina com o interesse do usuário e organiza a estrutura. Todo o conteúdo do módulo está diretamente relacionado com a rota. Logo faz sentido os componentes estarem dentro do módulo.
|-- pedido // Module
|-- novo
|-- novo-pedido.component .|html|scss|spec|.ts
|-- editar
|-- editar-pedido.component .|html|scss|spec|.ts
|-- detalhes
|-- detalhes-pedido.component .|html|scss|spec|.ts
|-- pedido.service.ts
|-- pedido.module.ts
|-- pedido.routes.ts
Trabalhar com módulos há ganhos significativos na inicialização da aplicação. É inimaginável uma aplicação Angular de médio porte sem módulos lazy load. E essa estrutura é coesa, mantém os grupos de interesse dentro de um mesmo local.
Core
O core module deve conter serviços singleton, componentes universais e outros recursos em que há uma instância única. Autenticação, header, interceptors são exemplos de componentes que terá apenas uma instância ativa para a aplicação e será utilizado praticamente por todos os modules.
Shared
O shared é onde todos os componentes compartilhados, pipes, filters e services devem ir. O shared pode ser importado em qualquer module. Assim esses itens serão reutilizados. O shared module deve ser independente do restante do aplicativo. Portanto, não deve ter referências de outro módulo.
Conclusão
Não há balas de prata a respeito de estruturas de pastas do Angular, isso depende do tamanho e objetivo da aplicação. Este artigo foi criado para abordar uma estrutura de pasta da versão 5 do Angular, no entanto a versão 6 que saiu essa semana, 20/05/2018, não houve grandes modificações que comprometem a abordagem.
Gostou? Sugestões? Quer complementar ou expor sua visão? Deixe seu comentário e vamos conversar!
Referencias
- Angular Style Guide
- Jonh Papa - Angular App Structuring Guidelines
- John Papa - Angular Structure: Refactoring for Growth
- Tom Crowley - Angular Folder Structure
- Mathis Garberg - How to define a highly scalable folder structure for your Angular project
Comments