Architecture 2025 : feature-modules vs standalone components

Architecture 2025 : feature-modules vs standalone components

Quand garder des feature-modules, quand passer en standalone en 2025, et comment refactorer sans casse.

Quand garder des feature-modules, quand passer en standalone en 2025, et comment refactorer sans casse.

Les standalone components sont matures, mais les feature-modules restent utiles. Voici un guide de découpage 2025.

Quand garder un feature-module ?

  • Frontières claires : domaines métier étanches (facturation, auth) avec providers scindés.
  • Lazy load massif : gros bundles séparés (ex: back-office) où la configuration de providers/route guards reste groupée.
  • Lib partagée : packaging en library Angular pour réutilisation externe.

Quand passer en standalone ?

  • Pages et UI : pages, composants, directives et pipes qui vivent dans l'app uniquement.
  • Micro-features : widgets isolés (search box, avatar menu) qui doivent être tree-shakés facilement.
  • Tests : composants plus simples à tester (TestBed.configureTestingModule({imports:[Cmp]})).

Stratégie de refactor

  1. Activer le standalone sur un composant feuille (pas sur un module racine).
  2. Remplacer NgModule.declarations par imports locaux.
  3. Supprimer progressivement les modules vides; conserver un AppConfig central avec provideRouter, provideHttpClient.
  4. Garder les feature-modules pour les domaines critiques et la configuration de providers.

Exemple de migration

// Avant
@NgModule({
  declarations: [ProfilePage],
  imports: [CommonModule, UiCardModule],
})
export class ProfileModule {}
// Après
@Component({
  standalone: true,
  selector: 'app-profile',
  imports: [CommonModule, UiCardComponent],
  template: `<ui-card>Profil</ui-card>`,
})
export class ProfilePage {}

Route :

{ path: 'profile', loadComponent: () => import('./profile.page').then((m) => m.ProfilePage) }

Patterns 2025

  • provideState / provideEffects (NGXS/NGRX) par feature pour garder le scope clair.
  • @defer sur les routes secondaires pour hydrater plus tard.
  • Utiliser des "composition roots" : un module ou un provide* par domaine pour les services, même si les composants sont standalone.

Indicateurs de fin de migration

  • Plus de SharedModule géant; préférer des UiButton, UiCard standalone importés localement.
  • Les routes lazy pointent vers des loadComponent ou des loadChildren mixtes (ok).
  • Les builds montrent une baisse du bundle vendor (tree-shaking des composants inutilisés).