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