Retour au Blog
AI & Development25 janvier 20269 min de lecture

Utiliser les assistants de code IA (Copilot, Claude Code) dans un workflow Angular

DR

Doug Ribeiro

9 min de lecture

Les trois premiers mois où j'ai utilisé Copilot, j'ai accepté trop de suggestions. J'étais un développeur senior avec environ dix ans de front-end à l'époque, sur Angular depuis 2017, et j'ai quand même mergé des bogues subtils parce que le code généré semblait plausible. Une chaîne RxJS qui utilisait switchMap là où j'avais besoin d'exhaustMap. Une mise à jour de signal qui contournait le contrat d'immutabilité. Un composant avec un abonnement qui n'était jamais nettoyé. Le code compilait. Les tests passaient parce qu'ils étaient générés par le même outil et testaient le même mauvais comportement. J'ai commencé à être plus sélectif après ça.

GitHub CopilotComplétions en ligne dans l'édi…Mode agent dans VS Code, éditio…Un agent de code qui travaille …Instructions personnalisées du …Revue de code et résumés de PR …Claude CodeTourne dans le terminal, pas da…Lit le dépôt lui-même au lieu d…Un fichier d'instructions de pr…Travail en plusieurs étapes : é…Scriptable, donc utilisable com…VS

Les deux ne se concurrencent pas tant sur les fonctionnalités que sur l'endroit où ils se placent. Copilot vit dans l'éditeur et complète ce que je suis en train de taper. Claude Code vit dans le terminal et travaille sur le dépôt : il lit des fichiers que je n'ai pas ouverts, fait une modification répartie sur plusieurs d'entre eux, lance la suite de tests et réagit à ce qui a échoué. L'autre différence, c'est l'endroit où se trouve la politique. Copilot Business répond à l'administrateur d'une organisation, et c'est pour ça que c'était celui que j'utilisais au travail. Sur mes propres projets, personne d'autre que moi ne fixe cette politique.

À quoi les outils IA sont réellement bons

Les gains sont réels dans les bonnes catégories. Toute tâche structurelle et répétitive, où la forme de la sortie est bien définie et où je ne ferais que remplir un pattern que je connais déjà, l'IA est plus rapide que moi. Toute tâche qui nécessite du jugement sur l'architecture, les règles métier ou la justesse comportementale subtile, l'IA est une distraction.

  • Scaffolding de nouveaux composants et services qui suivent les patterns déjà dans le codebase
  • Écriture de cas de test Jest pour un composant une fois que l'implémentation existe
  • Génération d'interfaces TypeScript à partir de formes de réponses API ou d'exemples JSON
  • Rédaction de patterns regex et de fonctions de formatage de dates
  • Refactoring de blocs de code répétitifs en utilitaires partagés
  • Suggestion d'opérateurs RxJS quand vous décrivez le comportement voulu en langage naturel

Le gain de scaffolding sur un service Angular typique se ressent facilement. Dans un codebase Angular actuel, écrire un nouveau service avec signals, gestion d'erreurs et patterns takeUntilDestroyed, en suivant les conventions du codebase, est un travail lent et minutieux sans IA. Avec Copilot référençant un service existant comme template, ça devient une courte passe avec un tour de corrections. C'est du temps réellement gagné, et ça se cumule sur chaque service qu'une équipe ajoute.

Le problème de version Angular

Angular a plus changé entre v14 et v19 qu'à n'importe quel autre moment de son histoire. Composants standalone, signals, nouvelle syntaxe de flux de contrôle, inject() remplaçant l'injection par constructeur dans la plupart des patterns, guards fonctionnels, et du côté NgRx, le Signal Store. Les outils IA entraînés sur du code pré-v16 génèreront avec confiance les anciens patterns. Ils semblent corrects. Ils compilent. Ils ne sont juste pas comment on écrit du Angular aujourd'hui.

  • Déclarations de composants basées sur NgModule au lieu de standalone: true
  • Injection par constructeur au lieu de inject()
  • Teardown ngOnDestroy basé sur Subject au lieu de takeUntilDestroyed
  • ngIf et ngFor au lieu de la syntaxe @if et @for
  • Anciens patterns NgRx au lieu de Signal Store pour l'état de fonctionnalité
  • Injection par constructeur de ActivatedRoute au lieu de la nouvelle approche de binding d'input

Je revois chaque snippet Angular généré par IA pour ces problèmes avant de l'accepter. Ça prend environ 15 secondes. Si l'outil génère un constructeur avec des dépendances injectées, je le convertis. Ce n'est pas la faute de l'IA. C'est un problème de date de coupure des connaissances et de données d'entraînement. La correction est de connaître les patterns actuels assez bien pour attraper les lacunes.

Comment j'utilise Claude Code sur mes propres projets

Sur mes propres projets, c'est-à-dire mon SaaS et le projet parallèle en vie à ce moment-là, ce que je veux c'est du code qui correspond au projet, pas du code qui correspond à la doc du framework. Je garde donc un fichier d'instructions de projet dans le dépôt qui décrit les conventions, et je pointe vers les fichiers précis dont je veux qu'une nouvelle pièce s'inspire. Le prompt ci-dessous est la forme qui fonctionne : nommer le fichier de référence, nommer les patterns, nommer les services partagés.

typescript
// Prompt approach that produces consistent results
// (illustrative; paths and names are generic):
// "Generate a JobApplicationService following the same patterns as
// src/app/features/inbox/services/inbox.service.ts
// Use inject() for dependencies, expose state via signals,
// handle errors with the ErrorHandlerService already in core,
// and include takeUntilDestroyed where needed."

// The output follows the project's conventions rather than
// the generic Angular answer, which is what you want
// in a codebase that already has standards.

@Injectable({ providedIn: 'root' })
export class JobApplicationService {
  private http = inject(HttpClient);
  private errorHandler = inject(ErrorHandlerService);

  private _applications = signal<JobApplication[]>([]);
  private _saving = signal(false);

  readonly applications = this._applications.asReadonly();
  readonly saving = this._saving.asReadonly();

  track(postingId: string, stage: ApplicationStage): Observable<JobApplication> {
    this._saving.set(true);

    return this.http
      .post<JobApplication>('/api/applications', { postingId, stage })
      .pipe(
        tap(application => {
          this._applications.update(list => [...list, application]);
          this._saving.set(false);
        }),
        catchError(err => {
          this._saving.set(false);
          return this.errorHandler.handle(err);
        })
      );
  }
}

Utiliser l'IA dans une banque : à quoi ressemblent les règles

Dans une banque, la conversation sur les outils IA n'est pas optionnelle. Les banques fixent des politiques sur quel code peut être envoyé à des services IA externes, et la version courte est généralement la même : pas de logique métier propriétaire, pas de données client, pas de contrats d'API internes. Chez BMO, l'assistant de l'équipe était GitHub Copilot Business, qui a les garanties de confidentialité des données d'entreprise. Je n'utilisais pas l'interface de chat pour coller du code de service interne ou des modèles de données.

En pratique ça signifiait que l'IA m'aidait avec les patterns Angular et la mécanique TypeScript, pas avec la logique du domaine de prêts. Je ne lui demandais pas de m'aider à implémenter un algorithme de décision de crédit ou une vérification de conformité réglementaire. Ceux-ci nécessitent un jugement et une revue humains, et les envoyer à une IA tierce est un risque de gouvernance des données même avec les tiers entreprise.

  • Utiliser des abonnements de grade entreprise avec des accords de traitement des données
  • Ne jamais coller d'identifiants, de chaînes de connexion, de secrets JWT ou de données personnelles dans une interface IA
  • Ne jamais coller de logique métier propriétaire ou de schémas d'API internes dans un chat IA public
  • Revoir le code généré comme vous revoyez la PR d'un développeur junior : supposer des erreurs, lire attentivement

Les garde-fous, et celui qui bloque réellement un merge

Les garde-fous viennent en couches et ils ne sont pas interchangeables. La couche instructions vient en premier : un fichier d'instructions dans le dépôt qui dit à l'assistant ce qu'est le codebase et ce qu'il ne doit jamais suggérer, et sur Copilot Business, l'exclusion de contenu, qui garde des chemins entiers hors du contexte du modèle dès le départ. Cette couche façonne ce qui est généré, et c'est celle que j'ai détaillée dans l'article sur les garde-fous IA dans un environnement bancaire. Elle ne décide pas de ce qui est mergé. C'est le pipeline qui décide. ESLint avec les règles angular-eslint, Jest avec un seuil de couverture, les quality gates SonarQube, tout ça sur chaque pull request. Si l'IA génère un pattern déprécié, le lint échoue et le merge est bloqué. Notez ce qui ne se produit pas automatiquement : si elle vous donne une méthode de service sans branche d'erreur, rien ne l'attrape à moins que quelqu'un n'ait écrit la règle de lint ou le test d'abord. Les deux couches sont complémentaires, et c'est l'ordre qui compte. Les instructions sont une demande qu'un modèle est libre d'ignorer. Un quality gate en échec n'est pas négociable. Si vous ne pouvez en construire qu'une seule ce trimestre, construisez le pipeline.

javascript
// eslint.config.js
// angular-eslint ships flat config from v18, and a v19 workspace
// generates this file instead of .eslintrc.json. These are the rules
// that catch what an AI assistant gets wrong most often in Angular.
// @ts-check
const eslint = require('@eslint/js');
const tseslint = require('typescript-eslint');
const angular = require('angular-eslint');

module.exports = tseslint.config({
  files: ['**/*.ts'],
  extends: [
    eslint.configs.recommended,
    ...tseslint.configs.recommended,
    ...angular.configs.tsRecommended,
  ],
  processor: angular.processInlineTemplates,
  rules: {
    '@angular-eslint/prefer-standalone': 'error',
    '@angular-eslint/no-lifecycle-call': 'error',
    '@angular-eslint/use-injectable-provided-in': 'error',
    '@typescript-eslint/no-explicit-any': 'warn',
    '@typescript-eslint/explicit-function-return-type': 'warn',
    'no-console': ['error', { allow: ['warn', 'error'] }],
  },
});

Les outils IA donnent du levier au développeur qui connaît déjà le framework. Ils donnent une fausse confiance au développeur qui ne le connaît pas.

Mon évaluation globale après deux ans d'utilisation quotidienne : Copilot est celui que j'ai ouvert pendant que je tape, et Claude Code est celui à qui je confie une tâche entière quand le travail s'étend sur plusieurs fichiers et demande de lancer les tests. Les gains de vitesse sur le travail structurel répétitif sont réels et se composent sur un trimestre. La clé est de traiter chaque suggestion comme un point de départ, pas une solution. La revue prend des secondes. La sauter prend des minutes à corriger après, si vous l'attrapez.

Références

AIAngularClaude CodeCopilotDeveloper Tools