Checklist de revue de code Angular : toutes les étapes incluses

Nous cherchons tous à créer des applications de haute qualité, faciles à maintenir et sécurisées. Que vous prépariez une nouvelle version riche en fonctionnalités ou que vous mettiez à l’échelle votre produit pour un public plus large, des revues de code Angular approfondies sont essentielles. Pourquoi ? Parce qu’elles aident à découvrir des problèmes cachés, à maintenir un style de code uniforme et à garder votre flux de développement sur la bonne voie.

Dans cet article, nous aborderons :

Pourquoi la revue de code est importante pour Angular

Angular possède une structure modulaire alimentée par TypeScript, ce qui élimine déjà bon nombre des maux de tête que l’on rencontre en JavaScript classique. Même avec cette aide supplémentaire, cela ne signifie pas que vous pouvez ignorer les revues de code. Un “any” mal placé, une faille de sécurité négligée ou une architecture maladroite peut causer de gros problèmes. Une revue approfondie vous aidera à :

  • Garder votre code cohérent et facile à naviguer
  • Repérer les ralentissements de performance avant qu’ils n’augmentent votre facture de serveur
  • Renforcer la sécurité, en particulier autour des entrées générées par les utilisateurs
  • Favoriser un flux de données et de logique prévisible

Si vous cherchez encore plus de conseils sur l’importance des revues de code, consultez nos autres listes de contrôle pour Python, JavaScript et la sécurité.

Une architecture de projet claire

Un projet Angular bien structuré entraîne moins de conflits de fusion et une expérience d’intégration plus fluide pour les nouveaux développeurs. En séparant les fonctionnalités en modules, en décidant lesquelles se chargent en différé et en gardant des noms de fichiers logiques, vous préparez le terrain pour une maintenance et une évolutivité faciles.

Modules de fonctionnalité :

  • Regroupez les fonctionnalités liées sous des modules de fonctionnalité dédiés pour éviter l’encombrement de votre module principal et garder votre code découvrable
  • Utilisez des modules partagés pour les directives et les composants nécessaires à plusieurs fonctionnalités
  • Surveillez vos configurations de routage pour voir où le chargement différé peut améliorer les performances
// Naive routing: everything is loaded at once, which makes the final bundle bigger
const routes: Routes = [
  { path: 'dashboard', component: DashboardComponent },
  { path: 'profile', component: ProfileComponent },
  // ...
];

// With lazy loading, only fetch modules on demand
const routes: Routes = [
  {
    path: 'dashboard',
    loadChildren: () => import('./dashboard/dashboard.module')
      .then(m => m.DashboardModule)
  },
  {
    path: 'profile',
    loadChildren: () => import('./profile/profile.module')
      .then(m => m.ProfileModule)
  }
];

Organisation logique des dossiers :

  • Donnez à chaque dossier un objectif clair (composants, services, pipes, etc.) pour éviter d’enterrer des fichiers dans des emplacements aléatoires
  • Nommez les dossiers en fonction de leur fonctionnalité (par exemple, utilisateurs, produits, rapports), et non avec des termes abstraits comme divers ou général

Gestion des versions et CI/CD appropriées :

  • Étiquetez les versions dans Git et automatisez vos vérifications de build. Cela garantit que le nouveau code se fusionne correctement et que tout changement architectural est testé tôt
  • Identifiez rapidement les conflits potentiels avec un pipeline CI simple exécutant ng build –prod ainsi que des vérifications de lint

Des conventions de codage cohérentes

Les règles de style peuvent sembler cosmétiques au départ, mais un style cohérent augmente la productivité. Des outils comme Angular ESLint et Prettier automatisent la majeure partie du travail, tandis qu’un schéma de nommage standard maintient votre application uniforme.

Règles de linting et de formatage unifiées :

  • Accordez-vous sur un guide de style (par exemple, le guide de style Angular) afin que les développeurs ne perdent pas de temps sur des changements cosmétiques
  • Automatisez les corrections avec Prettier ou ESLint. Vous pouvez même les exécuter en tant que hook de pré-commit pour maintenir le dépôt propre. Consultez cet bref exemple de configuration ESLint, qui peut être facilement étendue avec des dizaines de plugins et de règles personnalisées :
{
  "root": true,
  "overrides": [
    {
      "files": [
        "*.ts"
      ],
      "parserOptions": {
        "project": [
          "tsconfig.json",
          "e2e/tsconfig.json"
        ],
        "createDefaultProgram": true
      },
      // Can add ready-to-go config of Airbnb or others styleguides
      "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended",
        "plugin:@angular-eslint/recommended",
        "plugin:@angular-eslint/template/process-inline-templates"
      ],
      "rules": {
        // ...
      }
  }]
}

Noms significatifs :

  • Utilisez des noms de variables et de fonctions descriptifs et évitez les placeholders courts comme val ou tmp. Angular privilégie la clarté
  • Appliquez un nommage cohérent aux classes, fichiers et répertoires. Par exemple, user-profile.component.ts ou auth.service.ts signalent mieux l’intention que data.component.ts ou logic.service.ts

Fonctions lisibles :

  • Gardez les méthodes courtes et ciblées. Si vous traitez plusieurs tâches dans une seule fonction, divisez-la en parties logiques
  • Il en va de même pour les classes entières : lorsqu’un service commence à servir également de bibliothèque utilitaire, il est temps de le diviser

Typage strict et utilisation de TypeScript

L’un des points forts d’Angular est TypeScript, qui détecte les erreurs tôt et rend votre flux de données explicite. L’utilisation excessive de “any” annule ces avantages et transforme le débogage en devinettes.

Utilisez les interfaces :

  • Définissez des structures de données afin de savoir exactement ce qui entre et sort de vos fonctions
  • Si vous retournez des informations utilisateur, créez une interface User pour cela

Voici un exemple rapide de la façon dont le typage échoue sans définition appropriée :

// Bad practice: using `any` everywhere, there is spelling error, which is not catched
function submitForm(event: any): any {
  event.preventDefaulr(); // runtime error!
  // ...
  return fetch(`https://api.example.com/users/${id}`)
    .then(res => res.json());
}


// Good practice: using interfaces gives ability to avoid common errors and easily access properties
function submitForm(event: MouseEvent | Keyboard): any {
  event.preventDefault();
  const isShiftKeyPressed = event.shiftKey;
  // ...
  return fetch(`https://api.example.com/users/${id}`)
    .then(res => res.json());
}

Utilisez le mode strict :

  • Activez “strict” dans votre tsconfig.json pour simplifier la détection des erreurs de frappe subtiles. C’est l’un des moyens les plus rapides d’améliorer la fiabilité de votre code

Génériques si approprié :

  • Utilisez des classes ou méthodes génériques uniquement si c’est nécessaire ; évitez de surcharger des types simples
// Bad practice: Not constraining generics 
class BadDataService {
    process(data: T): T {
        return data; // No type safety or validation
    }
}

// Good practice: Using type inference and constraints
function transformAndValidate>(
    input: T,
    transform: (data: T) => R,
    validator: (data: R) => boolean
): R | null {
    const transformed = transform(input);
    return validator(transformed) ? transformed : null;
}

Composants et templates légers

La structure d’Angular pilotée par les composants facilite la division de votre interface utilisateur, mais les grands composants peuvent toujours devenir encombrants. Répartissez la logique métier dans des services et nettoyez les templates des boucles lourdes ou des calculs.

Lifecycle Hooks bien utilisés :

  • Implémentez uniquement les hooks dont vous avez vraiment besoin. Les hooks inutilisés ajoutent de l’encombrement et de la confusion. Par exemple, désabonnez-vous des observables dans ngOnDestroy() si vous vous abonnez manuellement
  • N’oubliez pas d’utiliser la bonne interface dans le composant

Limitez la logique de template :

  • Un template submergé de boucles et de conditions imbriquées est difficile à déboguer. Pour résoudre ce problème, déplacez les transformations répétées dans un pipe ou une méthode de la classe du composant
  • Gardez votre HTML lisible en tirant parti judicieusement des directives Angular comme ngIf et ngFor

Refactorisez les composants surdimensionnés :

  • Si un seul composant atteint des centaines de lignes, il est temps de le diviser
  • Pour que votre composant principal reste concentré, déplacez le traitement des données vers un service ou un sous-composant

Injection de dépendances efficace

L’injection de dépendances est une caractéristique d’Angular, mais il est facile de mal l’utiliser. Trop de fournisseurs au niveau racine alourdiront votre application, et les singletons peuvent causer des effets secondaires cachés s’ils se retrouvent de manière inattendue dans l’état du store.

Portée des services :

  • Fournissez un service dans la portée racine uniquement si vous êtes sûr qu’il est utilisé dans toute l’application. Les singletons sont également idéaux pour l’optimisation car ils sont inclus dans le tree-shaking (n’oubliez pas de supprimer tous les liens directs vers les singletons)
  • Sinon, déclarez-le dans un module spécifique pour limiter sa portée. Cette approche empêche également les singletons involontaires lorsque vous n’avez besoin que d’instances de service localisées

Évitez les décharges :

  • Gardez les services ciblés : ne combinez pas d’utilitaires aléatoires ou de logique non connectée dans un seul service
  • Organisez le code par fonctionnalité : authentification, profils utilisateurs, analyse, etc.

Gestion d’état :

  • Utilisez un service pour stocker l’état global uniquement après mûre réflexion
  • Adoptez une bibliothèque de gestion d’état formelle comme NgRx pour les applications plus importantes ; c’est plus prévisible et plus facile à tester

Gestion d'état et flux de données

Les schémas de flux de données peuvent faire ou défaire votre projet Angular. Même si votre application est petite pour l’instant, une gestion incohérente des données pourrait entraîner des refactorisations majeures ultérieurement.

Schémas prévisibles :

  • Choisissez une approche de gestion d’état — NgRx, schémas basés sur Behavior Subject, ou une approche plus simple store-service — et tenez-vous-y.
  • Ne changez pas de schéma en cours de projet, car cela crée de la confusion.

Mises à jour immuables :

  • Gardez les données immuables. Évitez de modifier des tableaux ou des objets sur place pour prévenir des problèmes étranges avec la détection de changements d’Angular.
  • Créez de nouveaux objets au lieu de modifier ceux existants.
// Bad practice
export class ListComponent {
  @Input() list: Todo[] = [];

  // Bad: Directly mutating input array
  toggleListCompletion(item: ListItem): void {
    todo.completed = !todo.completed; // Change detection might miss this!
  }
}


// Good practice
export class ListComponent {
  @Input() list: ListItem[] = [];
  @Output() listChange = new EventEmitter();

  // Good: Creating new array with modified item
  onToggleListItem(listItem: ListItem): void {
    const updatedList = this.list.map(item => 
      item.id === listItem.id 
        ? { ...item, completed: !item.completed }
        : item
    );
    this.listChange.emit(updatedList);
  }
}

Gestion des abonnements :

  • Utilisez les `async pipes` dans les templates autant que possible afin qu’Angular gère le cycle de vie des abonnements pour vous.
  • Si vous vous abonnez manuellement, n’oubliez pas de vous désabonner dans `ngOnDestroy()`.

Optimisation des performances

Personne n’aime une application lente. Les optimisations intégrées d’Angular aident, mais vous pouvez en faire plus pour réduire les temps de chargement et garder l’interface utilisateur réactive.

Chargement paresseux (Lazy Loading) :

  • Ne chargez pas toutes les fonctionnalités d’emblée : cela ralentit l’expérience initiale.
  • Chargez vos modules paresseusement afin que les utilisateurs ne téléchargent que ce dont ils ont besoin. Utilisez également une stratégie de préchargement personnalisée pour améliorer encore l’expérience utilisateur.

Découvrez cet exemple d’une application complexe qui a implémenté une stratégie de préchargement personnalisée pour équilibrer le temps de chargement initial et la vitesse de navigation :

// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';

const routes: Routes = [
  {
    path: 'dashboard',
    loadChildren: () => import('./dashboard/dashboard.module')
      .then(m => m.DashboardModule),
    data: { expectedRole: 'manager' }
  },
  {
    path: 'settings',
    loadChildren: () => import('./settings/settings.module')
      .then(m => m.SettingsModule),
    data: { expectedRole: 'superuser' }
  },
  // ...
];

// Custom preloading strategy which checks user role 
import { Injectable } from '@angular/core';
import { PreloadStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';
Import { RolesManagementService} from 'services/roles-management.service';

@Injectable({ providedIn: 'root' })
export class CustomPreloadStrategy implements PreloadStrategy{

  constructor(
    private rolesManager: RolesManagementService
  ) {}

  preload(route: Route, load: () => Observable): Observable {
    return this.rolesManager.hasRole(route.data.expectedRole).pipe(
        switchMap(hasRole => hasRole ? load() : of(null)),
      );
  }
}

Détection OnPush :

  • Utilisez `ChangeDetectionStrategy.OnPush` pour les composants qui dépendent de données immuables et d’observables afin de réduire les vérifications inutiles, en particulier dans les composants complexes et de grande taille (tableaux, formulaires) et pour les mises à jour de données en temps réel.
  • Analysez votre application pour vérifier si OnPush réduit réellement les re-rendus et mettez en évidence les composants qui en bénéficient le plus.

Réduisez les dépendances :

  • Analysez régulièrement `package.json` pour identifier les bibliothèques volumineuses dont vous n’avez pas besoin. Même une seule bibliothèque lourde peut faire gonfler la taille de votre bundle.
  • Supprimez ou remplacez les dépendances rarement utilisées (ou qui peuvent être reproduites avec des méthodes natives) pour garder votre build plus petit et plus efficace.

Principes de sécurité

Angular offre des défenses intégrées comme la désinfection du DOM, mais vous devez toujours vérifier votre application pour les menaces potentielles. Ignorer la validation des entrées utilisateur ou l’enregistrement d’informations sensibles peut entraîner des violations de données.

Prévenir les attaques XSS :

  • Utilisez la désinfection par défaut d’Angular pour les URLs, le HTML et les styles. Ne la contournez pas à moins de savoir exactement pourquoi.
  • Évitez les appels directs à `innerHTML` ou `bypassSecurityTrustHtml` sauf si vous êtes absolument sûr que les données sont sûres.

Identifiants cachés :

  • Ne conservez jamais de clés API ou de jetons privés dans votre code source.
  • Vérifiez attentivement les fichiers d’environnement, les journaux de console et les instructions de débogage pour toute fuite.

Analyses de dépendances :

  • Surveillez et mettez à jour les packages tiers obsolètes ; ils peuvent exposer toute votre application.
  • Des outils comme `npm audit` ou SonarQube signalent les vulnérabilités afin que vous puissiez les corriger rapidement.
  • Intégrez des contrôles automatisés dans votre pipeline CI/CD, bloquant les fusions si des vulnérabilités critiques apparaissent.

Tests complets

Une suite de tests robuste intercepte les régressions avant qu’elles n’atteignent la production. Couvrez vos composants, services et votre logique de routage, en vous concentrant d’abord sur les chemins critiques.

Tests unitaires :

  • Utilisez `TestBed` d’Angular pour les composants, en vous concentrant sur la façon dont ils interagissent avec les services et les entrées utilisateur.
  • Pour les services, testez chaque méthode en profondeur, en simulant les appels réseau ou les dépendances externes pour isoler la logique.

Tests d’intégration et de bout en bout (E2E) :

  • Utilisez des frameworks comme Cypress ou Protractor (en notant le mode maintenance de Protractor) pour simuler des flux utilisateur réels, en vous assurant que tout fonctionne ensemble.
  • Rédigez des tests pour les parcours utilisateur clés — tels que l’inscription, le passage à la caisse et la gestion de profil — pour découvrir les problèmes qui pourraient ne pas apparaître dans des tests unitaires isolés.

Couverture significative :

  • Un pourcentage de couverture n’est qu’un chiffre. Vous devez toujours vérifier que vos tests vérifient réellement le comportement, et pas seulement qu’ils parcourent des lignes de code.
  • Privilégiez la qualité à la quantité. Il vaut mieux avoir moins de tests, mais plus significatifs, qui couvrent la logique critique et les cas limites, qu’un grand nombre de tests superficiels qui ne font qu’augmenter les statistiques de couverture.

Votre partenaire Angular : Services de développement et d'audit

Nous exploitons Angular depuis ses débuts, en proposant des solutions sur mesure aux entreprises technologiques du monde entier.

Dans le cas de notre client C!A, nous avons utilisé Angular pour créer un front-end robuste pour son application web Current. Current est un système de prestation de services publics utilisé par les fonctionnaires de plus de 10 agences d’État et de comté américaines pour traiter des milliers de demandes de services à l’échelle nationale. Si vous souhaitez en savoir plus, consultez l’étude de cas.

Notre travail avec CDP Blitz a consisté à refactoriser une logique complexe en composants et services optimisés, à améliorer la stabilité, à réduire les temps de chargement des pages et à identifier rapidement les goulots d’étranglement cachés.

Par ailleurs, avec PageFreezer — une solution d’archivage numérique et de conformité — nous avons contribué à intégrer une gestion avancée des permissions utilisateur, à affiner les flux d’archivage de données et à introduire des tests systématiques pour maintenir une haute qualité de code sous de lourdes charges de données. N’hésitez pas à consulter l’étude de cas complète pour plus de détails.

Dans chaque mission, nous nous efforçons d’optimiser les applications Angular pour qu’elles restent stables, sécurisées et prêtes à accueillir de nouvelles fonctionnalités. Si vous souhaitez savoir comment nous abordons les tâches de front-end en Angular, React ou Vue, consultez notre page de développement web ou visitez notre blog pour plus d’informations. Et si vous envisagez de mettre à jour votre base de code Angular ou de construire quelque chose à partir de zéro, nous sommes là pour transformer vos idées en solutions concrètes.

En suivant cette checklist d’examen de code Angular, vous développerez des applications maintenables et performantes qui résisteront à l’épreuve du temps. Continuez d’affiner vos processus à mesure que vos frameworks évoluent, et contactez-nous si vous êtes prêt à repousser les limites de votre projet. Nous aimons travailler avec des personnes qui, comme nous, apprécient de transformer de bonnes idées en logiciels performants.

Points clés à retenir

Ceci conclut notre liste de contrôle condensée d’examen de code Angular. En suivant ces points, vous éviterez de nombreux pièges cachés (et évidents) tout au long de votre parcours. N’oubliez pas de surveiller le style du code, de garder un œil sur vos dépendances et de ne jamais négliger la sécurité. Si vous rencontrez des problèmes ou vous sentez bloqué, contactez-nous. Nous aimons aider nos collègues développeurs à affiner et à améliorer leurs applications.

Nous faisons cela depuis 2005 et nous sommes impatients de voir votre projet Angular prospérer. Quand votre code est clair, vos utilisateurs le ressentent. Faisons en sorte que cela se produise.

Nous avons condensé cette liste de contrôle dans un PDF rapide d'une page que vous pouvez épingler dans votre espace de travail

Nous le déposerons dans votre boîte de réception plus rapidement que vous ne pouvez dire « npm install ».
Veuillez saisir votre adresse courriel professionnelle n'est pas un courriel professionnel