Avez-vous une question? (216) 97 656 803 hajjriadh@gmail.com
Angular

Structure et architecture d'un projet Angular

Un cours complet pour maîtriser Structure et architecture d'un projet Angular.

0 chapitres 0 QCM Accès gratuit
Dans cet article
  1. Objectifs

    • Être capable de créer un projet Angular avec Angular CLI
    • Connaître le rôle de chaque dossier et fichier d'un projet Angular
    • Comprendre l'architecture d'une application Angular : composants, services, directives, pipes et modules
    • Comprendre comment une application Angular démarre dans le navigateur
    • Savoir organiser les dossiers d'un projet qui grandit
  2. Présentation

    • Angular est un framework pour créer la partie Front-End des applications web en utilisant HTML, CSS et TypeScript, compilé en JavaScript.
    • Une application Angular est une SPA (Single Page Application) : le navigateur charge une seule page index.html, puis Angular affiche et remplace les vues sans recharger la page.
    • Une application Angular se compose de :
      • Des composants: la partie visible de l'application web (IHM). Chaque écran ou morceau d'écran est un composant.
      • Des services pour la logique applicative (calculs, accès aux données, appels HTTP). Les composants utilisent les services grâce à l'injection de dépendances.
      • Des directives: elles modifient le comportement ou l'affichage des éléments HTML (ngClass, @if, @for…).
      • Des pipes: ils formatent l'affichage des données dans les templates (dates, montants, majuscules…).
      • Des routes: elles associent une URL à un composant pour naviguer entre les vues.
      • Des modules (NgModule), facultatifs depuis les composants standalone: ils regroupent des composants, directives et pipes.

Structure et architecture d'un projet Angular

  1. Créer le projet

    • Le projet se crée avec Angular CLI (Node.js et Angular CLI doivent être installés) :
npm install -g @angular/cli
ng new mon-projet
cd mon-projet
ng serve -o
  • La commande ng new pose quelques questions (format des styles : CSS, SCSS… ; rendu côté serveur SSR). Pour débuter, choisissez CSS et répondez No au SSR.
  • ng serve -o compile le projet, lance un serveur de développement sur http://localhost:4200 et ouvre le navigateur. Chaque modification enregistrée recharge automatiquement la page.
  • L'arborescence d'un projet Angular

    • Voici la structure générée par ng new dans les versions récentes d'Angular :
    mon-projet/
    ├── node_modules/            # bibliothèques installées par npm (ne pas modifier, ne pas versionner)
    ├── public/                  # fichiers statiques copiés tels quels (favicon, images...)
    │   └── favicon.ico
    ├── src/                     # code source de l'application
    │   ├── app/                 # composant racine et code de l'application
    │   │   ├── app.ts           # classe du composant racine (app.component.ts dans les anciennes versions)
    │   │   ├── app.html         # template HTML du composant racine
    │   │   ├── app.css          # styles propres au composant racine
    │   │   ├── app.spec.ts      # tests unitaires du composant
    │   │   ├── app.config.ts    # configuration globale de l'application (providers)
    │   │   └── app.routes.ts    # déclaration des routes
    │   ├── index.html           # la page unique de la SPA
    │   ├── main.ts              # point d'entrée : démarre l'application
    │   └── styles.css           # styles globaux
    ├── .editorconfig            # règles d'édition communes (indentation, encodage)
    ├── .gitignore               # fichiers exclus de Git (node_modules, dist...)
    ├── angular.json             # configuration du projet pour Angular CLI
    ├── package.json             # dépendances et scripts npm
    ├── package-lock.json        # versions exactes installées
    ├── README.md                # documentation du projet
    ├── tsconfig.json            # configuration de TypeScript
    ├── tsconfig.app.json        # configuration TypeScript pour l'application
    └── tsconfig.spec.json       # configuration TypeScript pour les tests
    • Remarque : selon la version d'Angular, les fichiers du composant racine s'appellent app.ts / app.html / app.css ou app.component.ts / app.component.html / app.component.css, et les fichiers statiques sont dans public/ ou dans src/assets/. Le principe reste le même.
  • Les fichiers de configuration à la racine

    • package.json: situé à la racine, il définit les bibliothèques qui seront installées dans node_modules lors de l'exécution de npm install, ainsi que les scripts (npm start, npm run build, npm test).
    • angular.json: configuration utilisée par Angular CLI : nom du projet, fichier d'entrée (main.ts), styles globaux, dossier des fichiers statiques, dossier de sortie du build, options de développement et de production.
    • tsconfig.json: options du compilateur TypeScript (version de JavaScript générée, mode strict pour le typage fort…).
    • node_modules/: contient toutes les dépendances. Il est volumineux et se régénère avec npm install: il ne faut jamais le copier ni l'envoyer sur GitHub (il est déjà dans .gitignore).
    {
      "name": "mon-projet",
      "scripts": {
        "ng": "ng",
        "start": "ng serve",
        "build": "ng build",
        "test": "ng test"
      },
      "dependencies": {
        "@angular/common": "...",
        "@angular/core": "...",
        "@angular/forms": "...",
        "@angular/platform-browser": "...",
        "@angular/router": "...",
        "rxjs": "...",
        "tslib": "..."
      },
      "devDependencies": {
        "@angular/cli": "...",
        "@angular/compiler-cli": "...",
        "typescript": "..."
      }
    }
    • dependencies: bibliothèques nécessaires à l'exécution de l'application.
    • devDependencies: outils utilisés uniquement pendant le développement (CLI, compilateur, TypeScript).
  • Le démarrage d'une application Angular

    • Le démarrage suit toujours la même chaîne : index.html → main.ts → app.config.ts → composant racine App.
    • Exemple : src/index.html
    <!doctype html>
    <html lang="fr">
    <head>
      <meta charset="utf-8">
      <title>MonProjet</title>
      <base href="/">
      <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
      <app-root></app-root>
    </body>
    </html>
    • La balise <app-root> est vide : Angular va y afficher le composant racine. Les fichiers JavaScript compilés sont ajoutés automatiquement au build.
    • Exemple : src/main.ts
    import { bootstrapApplication } from '@angular/platform-browser';
    import { appConfig } from './app/app.config';
    import { App } from './app/app';
    
    bootstrapApplication(App, appConfig)
      .catch((err) => console.error(err));
    • bootstrapApplication démarre l'application en partant du composant racine App, avec la configuration appConfig.
    • Exemple : src/app/app.config.ts
    import { ApplicationConfig } from '@angular/core';
    import { provideRouter } from '@angular/router';
    import { routes } from './app.routes';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        provideRouter(routes)
        // plus tard : provideHttpClient() pour communiquer avec une API REST
      ]
    };
    • app.config.ts déclare les providers globaux : le routeur, le client HTTP, etc. Il remplace le tableau providers de l'ancien AppModule.
    • Exemple : src/app/app.routes.ts
    import { Routes } from '@angular/router';
    
    export const routes: Routes = [
      // { path: 'accueil', component: Accueil },
    ];
    1. Le Component

      • Dans Angular, tout est composant : un composant est une balise HTML personnalisée (ex : app-root, app-shop, app-login…).
      • Défini par: 1 sélecteur (le nom de la balise), 1 template, 1 ou plusieurs fichiers de style CSS (facultatif).
      • Représenté par: 1 fichier TypeScript (.ts), 1 fichier HTML (.html), 1 fichier CSS (facultatif) et 1 fichier de test (.spec.ts).
      • Un composant peut utiliser d'autres composants : l'application forme un arbre de composants dont la racine est App.
      • Exemple : src/app/app.ts
    import { Component } from '@angular/core';
    import { RouterOutlet } from '@angular/router';
    
    @Component({
      selector: 'app-root',          // nom de la balise HTML
      imports: [RouterOutlet],       // composants, directives et pipes utilisés dans le template
      templateUrl: './app.html',     // la vue
      styleUrl: './app.css'          // les styles propres à ce composant
    })
    export class App {
      titre = 'Mon premier projet Angular';   // donnée affichée dans la vue
    }
    • Exemple : src/app/app.html
    <h1>{{ titre }}</h1>
    <router-outlet />
    • Le décorateur @Component attache des métadonnées à la classe : il indique à Angular que cette classe est un composant et où trouver sa vue et ses styles.
    • La classe contient les données et les méthodes; le template les affiche avec l'interpolation {{ }}: c'est le principe MVVM (la vue est liée au composant par le data binding).
    • <router-outlet /> est l'emplacement où le routeur affiche le composant correspondant à l'URL.
    • Pour générer un nouveau composant :
    ng generate component produits/liste-produits
    # forme courte
    ng g c produits/liste-produits
    1. Les services, directives et pipes

      • Service: classe décorée par @Injectable, qui contient la logique réutilisable et les accès aux données. Un composant l'obtient par injection de dépendances.
    // src/app/services/produit.service.ts   (ng g s services/produit)
    import { Injectable } from '@angular/core';
    
    @Injectable({ providedIn: 'root' })   // une seule instance pour toute l'application
    export class ProduitService {
      getProduits(): string[] {
        return ['Clavier', 'Souris', 'Écran'];
      }
    }
    // dans un composant
    import { Component, inject } from '@angular/core';
    import { ProduitService } from '../services/produit.service';
    
    @Component({
      selector: 'app-liste-produits',
      templateUrl: './liste-produits.html'
    })
    export class ListeProduits {
      private produitService = inject(ProduitService);
      produits = this.produitService.getProduits();
    }
    • Directive: modifie l'affichage ou le comportement du HTML. Exemple avec la syntaxe de contrôle de flux :
    @for (p of produits; track p) {
      <li>{{ p }}</li>
    } @empty {
      <li>Aucun produit</li>
    }
    • Pipe: formate une valeur dans le template, avec le symbole |:
    <p>{{ titre | uppercase }}</p>
    <p>{{ dateCommande | date:'dd/MM/yyyy' }}</p>
    1. Les modules (NgModule)

      • Le module est un bloc de code qui regroupe des éléments liés : composants, services, directives ou pipes. Pour Angular, un module est une classe avec le décorateur @NgModule.
      • Jusqu'à Angular 16, chaque application avait obligatoirement au moins un module : le module racine, appelé classiquement AppModule.
      • Depuis Angular 17, les projets sont créés par défaut avec des composants standalone: chaque composant déclare lui-même ce qu'il utilise dans imports, et l'application démarre sans AppModule.
      • Il est indispensable de connaître les NgModules : on les retrouve dans de nombreux projets existants, bibliothèques et tutoriels.
      • Exemple (ancienne structure) : src/app/app.module.ts
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    
    @NgModule({
      declarations: [AppComponent],
      imports: [BrowserModule, AppRoutingModule],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    • Les propriétés les plus importantes sont :
      • declarations: les composants, directives et pipes qui appartiennent au module.
      • imports: les autres modules dont ce module a besoin.
      • exports: les éléments utilisables par d'autres modules.
      • providers: les services disponibles dans le module.
      • bootstrap: le composant racine lancé au démarrage (uniquement dans le module racine).
    Élément Avec NgModule (ancienne structure) Standalone (structure actuelle)
    Démarrage platformBrowserDynamic().bootstrapModule(AppModule) bootstrapApplication(App, appConfig)
    Composant racine app.component.ts déclaré dans AppModule app.ts autonome
    Dépendances d'un composant imports du module imports du composant
    Services globaux providers de AppModule providers de app.config.ts
    Routes app-routing.module.ts app.routes.ts
    1. Organiser un projet qui grandit

      • Quand l'application grandit, on regroupe les fichiers par fonctionnalité plutôt que par type. Une organisation courante :
    src/app/
    ├── core/                 # éléments uniques chargés une fois (services globaux, guards, intercepteurs)
    │   ├── services/
    │   └── guards/
    ├── shared/               # éléments réutilisables partout (composants, pipes, directives)
    │   ├── components/
    │   ├── pipes/
    │   └── directives/
    ├── features/             # une sous-dossier par fonctionnalité
    │   ├── produits/
    │   │   ├── liste-produits/
    │   │   ├── detail-produit/
    │   │   └── produit.model.ts
    │   └── clients/
    ├── app.ts
    ├── app.html
    ├── app.config.ts
    └── app.routes.ts
    • core: ce qui n'existe qu'en un seul exemplaire dans l'application.
    • shared: ce qui est réutilisé dans plusieurs fonctionnalités.
    • features: un dossier par fonctionnalité métier (produits, clients, commandes…).
    • Un fichier .model.ts contient les interfaces TypeScript qui décrivent les données (ex : Produit).
  • Application

    • Créez un projet decouverte-angular avec ng new et lancez-le avec ng serve -o.
    • Créez un dépôt vide decouverte-angular sur GitHub, puis reliez-y votre projet (Angular CLI a déjà initialisé Git) :
    git add .
    git commit -m "Création du projet Angular"
    git branch -M main
    git remote add origin https://github.com/VOTRE-COMPTE/decouverte-angular.git
    git push -u origin main
    • Ouvrez chaque fichier de l'arborescence et retrouvez son rôle dans cette leçon.
    • Modifiez la propriété titre du composant racine et observez le rechargement automatique.
    • Remplacez le contenu de app.html par votre propre titre et une courte présentation.
    • Générez un composant features/accueil et affichez-le dans app.html avec sa balise <app-accueil /> (pensez à l'ajouter dans les imports du composant racine).
    • Générez un service core/services/message qui renvoie un message de bienvenue, injectez-le dans le composant Accueil et affichez le message.
    • Faites un commit à chaque étape et poussez votre travail sur GitHub.
    Lorsque vous déployez votre application, vous distribuez uniquement le résultat de la commande ng build (dossier dist/), pas les fichiers source, ni node_modules, ni les outils de génération.