Esta é uma aplicação educacional completa criada para ensinar definitivamente sobre Módulos no Angular 14. Cada arquivo está extensivamente comentado e organizado para facilitar o aprendizamento.
Veja a aplicação rodando no Vercel: https://modulos-angular14-edu-app.vercel.app/
- Leia na ordem: README.md → INSTALACAO.md → GUIA-RAPIDO.md
- Explore o código: Cada arquivo tem comentários explicativos
- Use o console: Veja os logs de carregamento dos módulos
- DevTools é seu amigo: Observe o lazy loading na aba Network
- Pratique: Faça os exercícios do EXERCICIOS.md
- ✅ O que são NgModules e por que usá-los
- ✅ Tipos de módulos: Root, Feature, Shared e Core
- ✅ Metadados do @NgModule: declarations, imports, exports, providers, bootstrap
- ✅ Lazy Loading de módulos para melhor performance
- ✅ Diferenças entre BrowserModule e CommonModule
- ✅ Diferenças entre forRoot() e forChild()
- ✅ Como organizar uma aplicação Angular em módulos
- ✅ Boas práticas e padrões de arquitetura
src/
├── app/
│ ├── app.module.ts # 🌳 ROOT MODULE
│ ├── app.component.ts # Componente raiz
│ ├── app.routes.ts # Configuração de rotas
│ │
│ ├── components/
│ │ └── home/ # Componente da página inicial
│ │
│ ├── core/ # ⚙️ CORE MODULE
│ │ ├── core.module.ts # Módulo singleton
│ │ └── services/
│ │ ├── logger.service.ts # Serviço de logging
│ │ └── config.service.ts # Configurações globais
│ │
│ ├── shared/ # 🔄 SHARED MODULE
│ │ ├── shared.module.ts # Módulo compartilhado
│ │ ├── components/
│ │ │ ├── card/ # Componente reutilizável
│ │ │ └── loading/ # Componente de loading
│ │ ├── directives/
│ │ │ └── highlight.directive.ts # Diretiva customizada
│ │ └── pipes/
│ │ └── truncate.pipe.ts # Pipe customizado
│ │
│ └── features/ # 📦 FEATURE MODULES
│ ├── produtos/
│ │ ├── produtos.module.ts # Feature module (Lazy)
│ │ ├── produtos-lista/ # Lista de produtos
│ │ └── produto-detalhe/ # Detalhe de produto
│ │
│ └── usuarios/
│ ├── usuarios.module.ts # Feature module (Lazy)
│ └── usuarios-lista/ # Lista de usuários
│
├── environments/ # Configurações de ambiente
├── index.html # HTML principal
├── main.ts # Ponto de entrada (bootstrap)
├── polyfills.ts # Polyfills
└── styles.css # Estilos globais
Um NgModule é uma classe decorada com @NgModule() que organiza e agrupa componentes, diretivas, pipes e serviços relacionados. Todo aplicativo Angular tem pelo menos um módulo (o módulo raiz).
@NgModule({
declarations: [], // Componentes, diretivas e pipes
imports: [], // Outros módulos
exports: [], // O que disponibilizar externamente
providers: [], // Serviços
bootstrap: [] // Componente raiz (só no AppModule)
})
export class MeuModulo { }Lista de componentes, diretivas e pipes que pertencem a este módulo.
Regras:
- Cada componente/diretiva/pipe pode ser declarado em apenas UM módulo
- São privados por padrão (só disponíveis dentro do módulo)
- Para compartilhar, precisa usar
exports
declarations: [
AppComponent,
HeaderComponent,
FooterComponent
]Lista de módulos cujas funcionalidades são necessárias neste módulo.
imports: [
BrowserModule, // Para aplicações browser
FormsModule, // Para formulários template-driven
RouterModule, // Para roteamento
MeuModuloCustom // Módulos customizados
]Lista de componentes, diretivas, pipes e módulos que podem ser usados por outros módulos que importarem este módulo.
Essencial em Shared Modules!
exports: [
CommonModule, // Re-exporta módulo
CardComponent, // Exporta componente
HighlightDirective, // Exporta diretiva
TruncatePipe // Exporta pipe
]Lista de serviços que estarão disponíveis para injeção de dependências.
Nota: No Angular 14+, prefira usar providedIn: 'root'
providers: [
AuthService,
DataService
]Define o componente raiz que será inicializado. Apenas no módulo raiz!
bootstrap: [AppComponent]O módulo raiz da aplicação. Existe apenas um.
Características:
- ✅ Usa
BrowserModule - ✅ Usa
RouterModule.forRoot() - ✅ Tem a propriedade
bootstrap - ✅ Importa CoreModule
- ✅ Pode importar SharedModule
Arquivo: src/app/app.module.ts
@NgModule({
imports: [
BrowserModule, // Apenas no AppModule
RouterModule.forRoot([]), // forRoot() apenas aqui
CoreModule, // Uma vez
SharedModule // Pode importar
],
bootstrap: [AppComponent] // Apenas no AppModule
})
export class AppModule { }Organizam funcionalidades específicas da aplicação.
Características:
- ✅ Usa
CommonModule(não BrowserModule) - ✅ Usa
RouterModule.forChild() - ✅ Podem usar Lazy Loading
- ✅ Podem importar SharedModule
- ❌ NÃO usa BrowserModule
- ❌ NÃO usa forRoot()
- ❌ NÃO tem bootstrap
Exemplos neste projeto:
ProdutosModule-src/app/features/produtos/produtos.module.tsUsuariosModule-src/app/features/usuarios/usuarios.module.ts
@NgModule({
imports: [
CommonModule, // Sempre CommonModule
RouterModule.forChild(routes), // forChild() em feature modules
SharedModule // Importa recursos compartilhados
]
})
export class ProdutosModule { }Lazy Loading:
No arquivo de rotas principal (app.routes.ts):
{
path: 'produtos',
loadChildren: () => import('./features/produtos/produtos.module')
.then(m => m.ProdutosModule)
}Benefícios:
- 📉 Bundle inicial menor
- ⚡ Carregamento mais rápido
- 🎯 Código carregado sob demanda
Contém componentes, diretivas e pipes reutilizáveis.
Características:
- ✅ Usa
exportsextensivamente - ✅ Importado em múltiplos módulos
- ✅ Re-exporta módulos comuns (CommonModule)
- ❌ NÃO deve ter
providers - ❌ NÃO deve ter serviços
Arquivo: src/app/shared/shared.module.ts
@NgModule({
declarations: [
CardComponent,
LoadingComponent,
HighlightDirective,
TruncatePipe
],
imports: [
CommonModule
],
exports: [
CommonModule, // Re-exporta
CardComponent, // Disponibiliza externamente
LoadingComponent,
HighlightDirective,
TruncatePipe
],
providers: [] // SEMPRE VAZIO!
})
export class SharedModule { }Por que NÃO ter providers?
Cada módulo que importa o SharedModule criaria uma nova instância do serviço, quebrando o padrão singleton.
Contém serviços singleton e recursos globais.
Características:
- ✅ Importado APENAS no AppModule
- ✅ Tem guard para prevenir reimportação
- ✅ Contém serviços singleton
- ✅ Usa
@Optionale@SkipSelf - ❌ NÃO deve ser importado em feature modules
Arquivo: src/app/core/core.module.ts
@NgModule({
providers: [
LoggerService,
ConfigService
]
})
export class CoreModule {
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
if (parentModule) {
throw new Error('CoreModule já foi carregado!');
}
}
}O que colocar no Core Module:
- Serviços de autenticação
- Guards de navegação
- HTTP Interceptors
- Configurações globais
- Serviços de logging
- ✅ Usa no AppModule (módulo raiz)
- ✅ Necessário para aplicações browser
- ✅ Fornece diretivas:
*ngIf,*ngFor,*ngSwitch - ✅ Registra serviços essenciais do browser
- ❌ Use apenas uma vez no AppModule
- ✅ Usa em Feature Modules
- ✅ Fornece as mesmas diretivas do BrowserModule
- ✅ Pode ser usado múltiplas vezes
- ✅ Mais leve que BrowserModule
Regra de Ouro:
AppModule → BrowserModule
Feature Modules → CommonModule
- ✅ Usa no AppModule
- ✅ Configura o router globalmente
- ✅ Registra serviços de roteamento
- ❌ Use apenas uma vez
RouterModule.forRoot(routes)- ✅ Usa em Feature Modules
- ✅ Registra rotas adicionais
- ✅ Não registra serviços novamente
- ✅ Pode ser usado múltiplas vezes
RouterModule.forChild(routes)- Node.js 16+ instalado
- npm ou yarn
# 1. Clone ou navegue até o diretório do projeto
cd modulos-angular14-edu-app
# 2. Instale as dependências
npm install
# 3. Execute o projeto
npm start
# 4. Abra no navegador
# http://localhost:4200npm run build- Abra o DevTools (F12)
- Vá para a aba Network
- Recarregue a página inicial
- Note que apenas o bundle principal é carregado
- Clique em "Produtos" no menu
- Observe um novo chunk sendo carregado (produtos-module.js)
- Faça o mesmo com "Usuários"
Isso demonstra o Lazy Loading em ação! 🎉
-
Um módulo raiz
- Tenha apenas um AppModule
-
Feature modules para funcionalidades
- Organize código relacionado junto
-
Lazy loading para feature modules
- Melhora performance inicial
-
Shared module para reutilizáveis
- Evita duplicação de código
-
Core module para singletons
- Serviços globais em um lugar
-
providedIn: 'root' para serviços
- Moderna e tree-shakeable
-
NÃO use BrowserModule em feature modules
- Use CommonModule
-
NÃO declare o mesmo componente em múltiplos módulos
- Cada declaração é única
-
NÃO coloque providers no SharedModule
- Criaria múltiplas instâncias
-
NÃO importe CoreModule em feature modules
- Apenas no AppModule
-
NÃO use forRoot() em feature modules
- Use forChild()
Ao criar um novo módulo, pergunte-se:
- Usa BrowserModule?
- Usa forRoot()?
- Tem bootstrap?
- É o único módulo raiz?
- Usa CommonModule?
- Usa forChild()?
- Agrupa funcionalidade relacionada?
- Usa lazy loading (opcional)?
- Exporta componentes/diretivas/pipes?
- Pode ser importado múltiplas vezes?
- NÃO tem providers?
- Re-exporta CommonModule?
- Importado apenas no AppModule?
- Tem guard anti-reimportação?
- Contém serviços singleton?
- Usa @Optional e @SkipSelf?
Este é um projeto educacional. Sinta-se à vontade para:
- Adicionar mais exemplos
- Melhorar comentários
- Corrigir erros
- Sugerir melhorias
Este projeto é livre para uso educacional.
Parabéns! 🎉 Agora você tem um conhecimento sólido sobre módulos no Angular 14.
Principais aprendizados:
- NgModules organizam a aplicação em blocos coesos
- Root Module (AppModule) é único e inicializa a aplicação
- Feature Modules organizam funcionalidades e podem usar lazy loading
- Shared Module contém recursos reutilizáveis e EXPORTA tudo
- Core Module contém serviços singleton e é importado apenas uma vez
- Use BrowserModule no AppModule e CommonModule em feature modules
- Use forRoot() no AppModule e forChild() em feature modules
Continue praticando e explorando o código-fonte desta aplicação! 💪
Cada arquivo está extensivamente comentado para facilitar seu aprendizado. Leia, experimente, modifique e aprenda! 🚀