Aller au contenu principal

Modules vs Standalone

Standalone Components (Modern - Default)

Standalone est l'approche par défaut et recommandée pour Angular 17+.

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
selector: 'app-user',
standalone: true,
imports: [CommonModule],
template: `<p>User component</p>`
})
export class UserComponent {}

Bootstrapping Standalone

// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { provideRouter } from '@angular/router';

bootstrapApplication(AppComponent, {
providers: [
provideHttpClient(),
provideRouter(routes),
UserService
]
});

Standalone App Component

import { Component } from '@angular/core';
import { RouterOutlet, RouterLink } from '@angular/router';
import { CommonModule } from '@angular/common';

@Component({
selector: 'app-root',
standalone: true,
imports: [
CommonModule,
RouterOutlet,
RouterLink,
UserListComponent
],
template: `
<nav>
<a routerLink="/">Home</a>
<a routerLink="/users">Users</a>
</nav>
<router-outlet></router-outlet>
`
})
export class AppComponent {}

Routes Standalone

import { Routes } from '@angular/router';

export const routes: Routes = [
{
path: '',
loadComponent: () => import('./home/home.component')
.then(m => m.HomeComponent)
},
{
path: 'users',
loadComponent: () => import('./users/user-list.component')
.then(m => m.UserListComponent)
},
{
path: 'admin',
loadChildren: () => import('./admin/admin.routes')
.then(m => m.ADMIN_ROUTES)
}
];

Chargement Différé Standalone

// admin.routes.ts
import { Routes } from '@angular/router';

export const ADMIN_ROUTES: Routes = [
{
path: '',
loadComponent: () => import('./admin-dashboard.component')
.then(m => m.AdminDashboardComponent)
},
{
path: 'users',
loadComponent: () => import('./admin-users.component')
.then(m => m.AdminUsersComponent)
}
];

Mélanger Modules et Standalone

// Importer un composant standalone dans NgModule
@NgModule({
imports: [
BrowserModule,
UserComponent // Composant standalone
],
declarations: [AppComponent]
})
export class AppModule {}

// Importer NgModule dans un composant standalone
@Component({
standalone: true,
imports: [
CommonModule,
ReactiveFormsModule // NgModule
]
})
export class FormComponent {}

Providers dans Standalone

// Niveau composant
@Component({
standalone: true,
providers: [UserService] // Nouvelle instance par composant
})
export class UserComponent {}

// Niveau application
bootstrapApplication(AppComponent, {
providers: [
{ provide: API_URL, useValue: 'https://api.example.com' },
UserService // Singleton
]
});

// Niveau service
@Injectable({ providedIn: 'root' })
export class UserService {}

Imports Courants

// Toujours importer ces modules quand nécessaire
import { CommonModule } from '@angular/common'; // *ngIf, *ngFor, pipes
import { FormsModule } from '@angular/forms'; // ngModel
import { ReactiveFormsModule } from '@angular/forms'; // Reactive forms
import { RouterModule } from '@angular/router'; // routerLink, router-outlet
import { HttpClientModule } from '@angular/common/http'; // Legacy
// Ou
import { provideHttpClient } from '@angular/common/http'; // Standalone

Conseils de Migration

De NgModule vers Standalone:

  1. Ajouter standalone: true au @Component
  2. Ajouter le tableau imports: []
  3. Importer les modules/composants nécessaires
  4. Retirer des declarations du NgModule
  5. Mettre à jour le routing pour utiliser loadComponent

Exemple:

// Avant
@Component({
selector: 'app-user'
})

@NgModule({
declarations: [UserComponent]
})

// Après
@Component({
selector: 'app-user',
standalone: true,
imports: [CommonModule]
})

Avantages de Standalone

  • Plus simple - Pas besoin de NgModules
  • Plus rapide - Meilleur tree-shaking
  • Explicite - Dépendances claires
  • Lazy loading - Au niveau du composant
  • Moins de boilerplate
  • Meilleure DX - Plus facile à comprendre

NgModules (Legacy)

Utiliser uniquement les NgModules pour les applications legacy ou lors de la maintenance de code existant.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

@NgModule({
declarations: [AppComponent, UserComponent],
imports: [BrowserModule],
providers: [UserService],
bootstrap: [AppComponent]
})
export class AppModule {}

Quand Utiliser Chacun

Utiliser Standalone (Recommandé)

  • Toutes les nouvelles applications (Angular 17+)
  • Bibliothèques de composants
  • Meilleur tree-shaking et performance
  • Dépendances plus simples et plus explicites

Utiliser NgModules (Legacy uniquement)

  • Maintenir des applications basées sur NgModule existantes
  • Migration graduelle depuis une ancienne base de code

Bonnes Pratiques

  • Toujours utiliser standalone pour les nouvelles applications Angular 17+
  • Utiliser bootstrapApplication() pour l'initialisation de l'application
  • Utiliser provideHttpClient() au lieu de HttpClientModule
  • Importer uniquement ce dont vous avez besoin dans chaque composant
  • Utiliser loadComponent pour le lazy loading
  • Garder le tableau imports organisé et minimal