AngularJS a depuis longtemps atteint sa fin de vie : pas de correctifs de sécurité, pas de mises à jour de dépendances et un nombre de développeurs qui le connaissent de plus en plus réduit. Continuer à maintenir une application AngularJS en production signifie accumuler risque de sécurité, dette technique et coût d'embauche. Ce guide couvre l'intégralité du parcours vers Angular moderne : audit du code existant, choix entre le big bang et la migration incrémentielle du modèle Strangler, bootstrap hybride avec ngUpgrade, cartographie conceptuelle directe (contrôleur, directive, $http, routage, authentification), tests, performances et un plan opérationnel de 30/60/90 jours avec des KPI mesurables.
Pourquoi migrer d'AngularJS vers Angular
Le passage d'AngularJS à Angular n'est pas une simple mise à niveau de version : il s'agit d'un changement de paradigme, d'un framework basé sur une liaison de données bidirectionnelle et $scope omniprésente à un modèle composants avec injection de dépendances typées, changement Détection optimisée et compilation AOT. Les avantages sont mesurables – des bundles plus petits grâce au TypeScript de bout en bout, un écosystème activement maintenu – mais doivent être mis en balance avec le risque réel d’une migration mal planifiée : régressions fonctionnelles, équipe bloquée pendant des mois, versions de fonctionnalités gelées.
Aperçu des avantages et des risques
| Avantages de la migration | Risques à gérer |
|---|---|
| Performances supérieures (détection de changement, AOT, tree-shaking) | Régressions fonctionnelles sur des fonctionnalités héritées non testées |
| TypeScript de bout en bout, moins de bugs au moment de l'exécution | Coût initial élevé sans libération immédiate de la valeur |
| Écosystème maintenu, sécurité mise à jour | Équipe apprenant un nouveau paradigme sous pression |
| Plus facile à trouver des développeurs sur le marché | Code hybride temporaire plus complexe à déboguer |
Évaluation initiale : audit du code AngularJS
Avant d'écrire une ligne d'Angular, vous devez définir précisément ce que vous migrez. Un audit superficiel est la cause la plus fréquente de mauvaises estimations et de migrations bloquées à mi-chemin. L'audit doit répondre à trois questions : quelle est la taille du code, dans quelle mesure il est couplé en interne et quelles dépendances externes sont impliquées.
Liste de contrôle d'audit opérationnel
- Inventaire des modules : Répertorie chaque module AngularJS (
angular.module(...)) et ses dépendances déclarées. - Nombre de contrôleurs/directives/services : Utilisez
grep -rn "\.controller(\|\.directive(\|\.factory(\|\.service(" src/) pour un décompte rapide et objectif. - Carte des $scopes partagés - Identifiez l'utilisation de
$rootScopepar état global – presque toujours le point idéal pour migrer vers les services Angular. - Dépendances spécifiques à AngularJS :
angular-ui-router,angular-translate,restangularn'ont pas d'équivalent direct et doivent être remplacé, non traduit ligne par ligne. - Couverture de tests existante : Sans tests, chaque refactor est un saut dans le noir ; mesurez la couverture actuelle avant de commencer.
- Classification par criticité : diviser les fonctionnalités en « core business » (risque élevé, migrer en dernier, avec plus de tests) et « périphériques » (bon point de départ).
Stratégie de migration : big bang vs incrémental (modèle étrangleur)
Il existe deux approches principales. Le big bang réécrit toute l'application en Angular avant de sortir quoi que ce soit : risqué sur les grosses applications, mais plus facile à raisonner sur les petits projets. Le strangler pattern (incrémental) permet à AngularJS et Angular de coexister dans la même application via ngUpgrade, en migrant une fonctionnalité à la fois et en la publiant continuellement : plus lentement à court terme, mais réduit considérablement les risques et permet à l'entreprise de continuer à recevoir de la valeur pendant la migration.
Comment choisir la bonne approche
| Critère | Big bang | Motif étrangleur (incrémental) |
|---|---|---|
| Taille de l'application | Petite/moyenne (< 50 composants) | Grande entreprise |
| Tolérance au risque de l'entreprise | Élevée (la version peut être bloquée) | Faible (continuité requise) |
| Équipe disponible | Dédié à temps plein à la migration | Réparti entre nouvelles fonctionnalités et migration |
| Couverture de test existante | Pas critique | Fortement recommandé |
Pour la plupart des applications d'entreprise réelles, le strangler pattern est le bon choix : il vous permet de valider chaque module migré en production avant de passer au suivant.
Configuration de l'environnement de développement
Avant de démarrer le refactor, vous devez installer et configurer correctement les bons outils, y compris le package @angular/upgrade qui permet l'interopérabilité entre les deux frameworks.
Liste de contrôle des outils nécessaires
# Verifica versioni installate
node -v # Node 20.x LTS o superiore
npm -v
# Installa Angular CLI globalmente
npm install -g @angular/cli
# Crea il progetto Angular che ospiterà il bootstrap ibrido
ng new my-app --routing --style=scss
cd my-app
# Installa il modulo di interoperabilità con AngularJS
npm install @angular/upgrade
# Installa AngularJS stesso come dipendenza (per il periodo ibrido)
npm install angular@1.8.3
Refactor et cartographie conceptuelle : d'AngularJS à Angular
La partie la plus délicate de la migration consiste à traduire correctement les concepts architecturaux. Chaque construction AngularJS a un équivalent Angular conceptuellement proche, mais avec une sémantique et un cycle de vie différents.
Tableau de cartographie conceptuelle
| AngularJS | Angular moderne |
|---|---|
$scope | Propriétés de classe de composants (this) |
$rootScope pour l'état global | Service @Injectable({ provideIn: 'root' }) avec ComportementSujet ou signal |
.controller() | Classe Component avec @Component() |
.directive() | Composant ou Directive (@Directive()) selon qu'il possède ou non un modèle |
.factory() / .service() | Classe avec @Injectable(), injectée via constructeur |
$http | HttpClient (RxJS observable au lieu de promesse) |
$route / ui-router | RouterModule avec route autonome ou chargé paresseux |
Reliure =, @, & | @Input(), @Output() avec EventEmitter |
Extrait 1–2 : Contrôleur → Composant
// AngularJS — controller
angular.module('app').controller('UserListController', function($scope, UserService) {
$scope.users = [];
$scope.loading = false;
$scope.loadUsers = function() {
$scope.loading = true;
UserService.getAll().then(function(res) {
$scope.users = res.data;
$scope.loading = false;
});
};
$scope.loadUsers();
});
// Angular — component equivalente
@Component({
selector: 'app-user-list',
standalone: true,
templateUrl: './user-list.component.html',
})
export class UserListComponent implements OnInit {
users: User[] = [];
loading = false;
constructor(private userService: UserService) {}
ngOnInit(): void {
this.loadUsers();
}
loadUsers(): void {
this.loading = true;
this.userService.getAll().subscribe((users) => {
this.users = users;
this.loading = false;
});
}
}
Extrait 3–4 : Directive complexe → Composant
// AngularJS — directive con isolate scope
angular.module('app').directive('userCard', function() {
return {
restrict: 'E',
scope: { user: '=', onSelect: '&' },
template: '<div class="card" ng-click="onSelect({user: user})">{{user.name}}</div>',
};
});
// Angular — component con Input/Output
@Component({
selector: 'app-user-card',
standalone: true,
template: `<div class="card" (click)="select.emit(user)">{{ user.name }}</div>`,
})
export class UserCardComponent {
@Input({ required: true }) user!: User;
@Output() select = new EventEmitter<User>();
}
Extrait 5–6 : Service AngularJS → Service Angular avec DI
// AngularJS — factory
angular.module('app').factory('UserService', function($http) {
return {
getAll: function() {
return $http.get('/api/users');
},
};
});
// Angular — servizio con HttpClient e DI
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) {}
getAll(): Observable<User[]> {
return this.http.get<User[]>('/api/users');
}
}
Extrait 7 à 8 : Routage et appels HTTP
// AngularJS — ui-router
$stateProvider.state('users.detail', {
url: '/users/:id',
template: '<user-detail user-id="$resolve.userId"></user-detail>',
resolve: {
userId: ['$stateParams', function($stateParams) { return $stateParams.id; }],
},
});
// Angular — Router standalone con lazy loading
export const routes: Routes = [
{
path: 'users/:id',
loadComponent: () =>
import('./user-detail/user-detail.component').then((m) => m.UserDetailComponent),
},
];
// Nel component: lettura del parametro via ActivatedRoute
export class UserDetailComponent implements OnInit {
userId = signal<string | null>(null);
constructor(private route: ActivatedRoute) {}
ngOnInit(): void {
this.userId.set(this.route.snapshot.paramMap.get('id'));
}
}
Authentification et gestion des états
Le flux d'authentification doit être repensé, et pas seulement traduit. Dans AngularJS, il est courant de gérer le jeton à $rootScope avec un intercepteur à $http ; dans Angular, le modèle correct est un AuthService centralisé avec un état réactif (BehaviorSubject ou signal) et un HttpInterceptorFn.
Migration du flux d'authentification
// auth.service.ts
@Injectable({ providedIn: 'root' })
export class AuthService {
private tokenSignal = signal<string | null>(localStorage.getItem('access_token'));
readonly isAuthenticated = computed(() => !!this.tokenSignal());
constructor(private http: HttpClient) {}
login(credentials: LoginPayload): Observable<AuthTokens> {
return this.http.post<AuthTokens>('/api/auth/login', credentials).pipe(
tap((tokens) => this.setTokens(tokens)),
);
}
refresh(): Observable<AuthTokens> {
return this.http.post<AuthTokens>('/api/auth/refresh', {}).pipe(
tap((tokens) => this.setTokens(tokens)),
);
}
private setTokens(tokens: AuthTokens): void {
localStorage.setItem('access_token', tokens.accessToken);
this.tokenSignal.set(tokens.accessToken);
}
}
// auth.interceptor.ts — funzione, non più basata su $http config
export const authInterceptor: HttpInterceptorFn = (req, next) => {
const token = localStorage.getItem('access_token');
const cloned = token ? req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }) : req;
return next(cloned);
};
Pour une gestion d'état plus large (pas seulement l'authentification), sur les applications d'entreprise complexes, il est préférable d'évaluer NgRx, qui offre un magasin centralisé prévisible ; Cependant, dans la plupart des cas, les services avec BehaviorSubject ou un signal sont suffisants et beaucoup plus faciles à maintenir que l'introduction d'un modèle complet de type Redux.
Intégration progressive avec ngUpgrade
ngUpgrade est le package officiel qui permet à un AngularJS et à une application Angular d'exécuter sur la même page, en même temps, en partageant des services et en communiquant entre les composants. C'est le cœur technique du motif étrangleur.
Amorçage hybride : exemple pratique
// main.ts — bootstrap ibrido con downgradeModule
import { setUpLocationSync } from '@angular/upgrade/static';
import { UpgradeModule } from '@angular/upgrade/static';
@NgModule({
imports: [BrowserModule, UpgradeModule, AppRoutingModule],
declarations: [UserCardComponent],
})
export class AppModule {
constructor(private upgrade: UpgradeModule) {}
ngDoBootstrap(): void {
this.upgrade.bootstrap(document.body, ['legacyApp']);
setUpLocationSync(this.upgrade);
}
}
// Espone il component Angular come directive AngularJS,
// utilizzabile nei template AngularJS esistenti senza riscriverli
angular
.module('legacyApp')
.directive('appUserCard', downgradeComponent({ component: UserCardComponent }));
// Espone un servizio AngularJS ad Angular, per riuso durante la transizione
angular.module('legacyApp').factory('legacyUserService', downgradeInjectable(UserService));
Avec cette configuration, un modèle AngularJS existant peut utiliser sans modification, tandis que les nouveaux composants Angular peuvent injecter des services AngularJS existants via upgradeInjectable, jusqu'à ce que ceux-ci soient également migrés.
Tests pendant la migration
Le code hybride est par nature plus fragile à tester : deux frameworks, deux cycles de digestion/détection de changement, deux lanceurs de tests différents cohabitent pendant des mois. La stratégie correcte est de conserver Karma/Jasmine sur le code AngularJS non encore migré, d'introduire Jest pour chaque nouveau composant angulaire (mode de surveillance plus rapide et meilleur) et de remplacer progressivement Protractor par (obsolète) Cypress pour E2E, qui ne dépend pas du framework sous-jacent et teste l'application telle que la voit l'utilisateur.
Tests de la liste de contrôle
- Ne supprimez pas les tests AngularJS existants tant que le module correspondant n'est pas complètement migré.
- Chaque nouveau composant angulaire nécessite des tests unitaires avant il est lié via
ngUpgrade, pas après. - Les E2E Cypress doivent couvrir les flux critiques de bout en bout, traversant à la fois les pages AngularJS et Angular pendant la période hybride.
- Surveillez la couverture globale à chaque sprint : elle ne doit jamais descendre en dessous du niveau d'avant la migration.
Optimisation des performances et du bundle
Pendant la période hybride, le bundle grandit inévitablement, car il contient à la fois AngularJS et Angular. Il est essentiel de surveiller cette croissance et de prévoir de supprimer AngularJS dès que le dernier module sera migré.
Liste de contrôle des performances
- Chargement paresseux agressif sur chaque route angulaire avec
loadComponent/loadChildren, afin de ne pas charger tout le nouveau code plus tôt. - AOT compilation toujours active en production (
ng buildl'utilise par défaut à partir de la CLI moderne). - L'analyseur de bundle est exécuté à chaque étape de la migration, pour vérifier qu'AngularJS est effectivement supprimé à la fin du voyage et ne reste pas "mort" dans le bundle.
- Chargement différentiel : Angular CLI génère automatiquement des bundles différenciés pour les navigateurs modernes/anciens en cas de besoin.
- Supprimez
angular(1.x) depackage.jsonet de chaque import dès que le dernier module AngularJS a été migré - c'est l'étape la plus souvent oubliée.
Stratégie de déploiement, CI/CD et rollback
Chaque module migré doit être publié derrière un feature flag, afin de pouvoir revenir instantanément à la version AngularJS en cas de régression critique, sans rollback complet du déploiement.
Indicateurs de fonctionnalités et restauration : exemple
// Semplice feature flag basato su configurazione remota
if (this.featureFlags.isEnabled('new-user-list-angular')) {
this.router.navigate(['/users']); // route Angular
} else {
window.location.href = '/legacy/users'; // route AngularJS esistente
}
Le pipeline CI/CD doit effectuer, pour chaque pull request : une version de production, une suite Jest/Karma, une suite Cypress sur les flux critiques et une vérification automatique de la taille du bundle avec un seuil maximum — une augmentation anormale du bundle est souvent le premier signe d'une dépendance AngularJS oubliée.
5 mini-guides pratiques prêts à publier
Mini-guide 1 — Convertir un contrôleur AngularJS en composant Angular
H1: Du contrôleur AngularJS au composant Angular : guide étape par étape
Intro : Le contrôleur est la première brique à migrer dans chaque module : la conversion en composant suit toujours le même schéma répétable.
Snippet (40-60 mots) : Un contrôleur AngularJS avec $scope devient une classe de composant angulaire : les propriétés sur $scope deviennent des propriétés de la classe, les méthodes restent des méthodes et l'initialisation qui s'est produite à la le contrôleur final se déplace vers ngOnInit(). Les dépendances injectées via les paramètres de fonction deviennent des paramètres de constructeur typés.
Structure : H2 "Identifier la portée du contrôleur" → H3 "Liste des propriétés et des méthodes" ; H2 « Créer une classe de composants » → H3 « Déplacer la logique d'initialisation » ; H2 "Mettre à jour le modèle".
FAQ courte : « Devez-vous migrer le modèle avec le contrôleur ? » → "Oui, toujours ensemble : changements de syntaxe de liaison (ng-click → (clic))." · « Puis-je quitter $scope temporairement ? » → "Non, il n'existe pas en Angular : il faut le supprimer contextuellement."
Mini-guide 2 — Migrer une directive complexe vers un composant Angular
H1: Migrer une directive AngularJS avec une portée isolée vers un composant angulaire
Intro : Les directives à portée isolée et contraignantes =/@/& sont le cas le plus courant et sont cartographiées presque 1:1 sur Entrée/Sortie.
Snippet (40-60 mots) : Une liaison = (bidirectionnelle) devient un @Input() combiné, si nécessaire, avec @Output() pour avertir le parent ; une liaison (fonction) & devient directement une @Output() avec EventEmitter. Le template en ligne de la directive devient le template/templateUrl du nouveau composant angulaire.
Structure : H2 "Analyser les liaisons de directive" → H3 "Mapper =, @, & aux entrées/sorties" ; H2 "Créer un composant" → H3 "Gérer la restriction : 'E' vs 'A'" ; H2 "Mettre à jour les utilisations dans les modèles".
FAQ courte : "Qu'arrive-t-il à restreindre : 'A' (directive d'attribut) ?" → "Devenez un @Directive() Angular sans modèle." · « Les liaisons bidirectionnelles sont-elles toujours prises en charge ? » → "Oui, par convention [(valeur)] avec entrée+sortie couplées."
Mini-guide 3 — Intégrer ngUpgrade pour un bootstrap hybride
H1: AngularJS + bootstrap hybride angulaire avec ngUpgrade
Intro : Le bootstrap hybride est l'étape habilitante pour l'ensemble de la stratégie incrémentale : sans lui, chaque migration est forcément un big bang.
Extrait (40-60 mots) : UpgradeModule.bootstrap() démarre les deux frameworks sur la même page ; downgradeComponent rend un composant angulaire utilisable dans les modèles AngularJS, upgradeComponent fait le contraire. downgradeInjectable/upgradeInjectable partagent des services entre les deux mondes, permettant une réutilisation immédiate sans dupliquer la logique.
Structure : H2 "Installer @angular/upgrade" → H3 "Configurer ngDoBootstrap" ; H2 "Exposer les composants angulaires à AngularJS" → H3 "downgradeComponent en pratique" ; H2 "Partager les services entre les deux frameworks".
FAQ courte : "ngUpgrade ralentit-il l'application ?" → "Un peu, pour la détection de double changement : c'est un coût temporaire, pas permanent." · "Combien de temps peut durer la phase hybride ?" → "De quelques semaines à plusieurs mois, selon la taille de l'application."
Mini-guide 4 — Migrer le routage du routeur ui vers le routeur angulaire
H1 : Du routeur ui au routeur angulaire : guide de migration de routage
Intro : Le routage est souvent le dernier élément à migrer, car il affecte l'ensemble de la structure de navigation de l'application.
Extrait (40-60 mots) : Chaque state du routeur ui devient un Route Angulaire : url devient path, template/controller deviennent component (ou loadComponent pour le chargement paresseux), et le resolve devient resolve Basé sur un service angulaire avec Resolve ou lisez simplement dans le composant via ActivatedRoute.
Structure : H2 "Mapper les états existants" → H3 "url → chemin, résoudre → Résoudre" ; H2 "Configurer les routes avec chargement paresseux" → H3 "loadComponent vs loadChildren" ; H2 "Gérer la coexistence avec setUpLocationSync".
FAQ courte : « Les deux routeurs peuvent-ils coexister ? » → "Oui, temporairement, avec setUpLocationSync pour synchroniser l'URL." · « Qu'est-ce que j'utilise à la place des états imbriqués du routeur ui ? » → "Routes angulaires imbriquées avec des routes enfants et ."
Mini-guide 5 — Implémenter l'authentification JWT et actualiser le jeton pendant la migration
H1 : Authentification JWT avec jeton d'actualisation lors de la migration AngularJS → Angular
Intro : Le flux d'authentification doit fonctionner de manière identique dans les pages toujours AngularJS et déjà Angular, partageant le même jeton.
Snippet (40-60 mots) : Centralise le token dans localStorage (ou cookie httpOnly, préférable pour la sécurité), lu à la fois par l'intercepteur $http AngularJS et depuis HttpInterceptorFn Angulaire. Un AuthService Angular exposé à AngularJS via downgradeInjectable évite la duplication de la logique de connexion/actualisation dans les deux frameworks pendant la période hybride.
Structure : H2 "Centraliser la gestion des jetons" → H3 "localStorage vs httpOnly cookies" ; H2 « Partager l'AuthService entre les deux frameworks » → H3 « downgradeInjectable en pratique » ; H2 "Gérer le rafraîchissement automatique sur 401".
FAQ courte : « Dois-je dupliquer la connexion dans les deux frameworks ? » → "Non, un seul Angular AuthService partagé via downgradeInjectable suffit." · « Comment puis-je gérer la déconnexion avec un jeton expiré ? » → "Interceptez les 401 dans les deux intercepteurs et redirigez vers la connexion centralisée."
Étude de cas : Migration d'une application d'entreprise
Un cas typique : application de gestion AngularJS avec 340 contrôleurs, 85 directives personnalisées et 6 ans de développement incrémental. Avec une approche de type étrangleur sur des équipes de 4 développeurs, la migration a duré 9 mois, avec des versions hebdomadaires continues tout au long de la période. Résultats mesurés à la fin du projet : bundle initial réduit de 38% (de 2,4Mo à 1,5Mo gzip) après suppression complète d'AngularJS, temps de chargement (Time to Interactive) amélioré de 44%, couverture des tests passée de 22% à 68% grâce aux nouveaux tests introduits en même temps que chaque composant migré. Effort estimé : environ 1 400 personnes/heures au total, dont 60 % concentrés sur les modules métiers de base migrés dans la seconde moitié du projet.
Foire aux questions
Combien de temps prend une migration d'AngularJS vers Angular ?
Varie de quelques semaines pour les petites applications à plus d'un an pour les applications de grande entreprise ; le modèle étrangleur vous permet de répartir l'effort sur plusieurs sprints sans bloquer les versions.
Dois-je utiliser ngUpgrade ?
Non, seulement si vous choisissez l'approche incrémentielle. Avec le big bang, cela n’est plus nécessaire, car il n’y a pas de période de coexistence entre les deux cadres.
NgRx est-il obligatoire après la migration ?
Non : Pour la plupart des applications, les services avec BehaviorSubject ou un signal sont suffisants ; NgRx ne convient qu'aux états très complexes partagés entre de nombreuses fonctionnalités.
Puis-je migrer uniquement certaines pages et laisser les autres dans AngularJS à long terme ?
Techniquement oui avec ngUpgrade, mais ce n'est pas recommandé en état permanent : cela augmente la complexité de la maintenance et le bundle reste plus lourd que nécessaire.
Comment gérer les bibliothèques tierces spécifiques à AngularJS ?
Ils doivent être remplacés par l'équivalent Angular ou une bibliothèque indépendante du framework ; il n'y a pas de traduction automatique pour les bibliothèques comme restangular ou angular-translate.
Le rapporteur est-il toujours utilisable pour les tests E2E ?
Il est obsolète par l'équipe Angular : pour les nouveaux projets ou migrations nous recommandons Cypress, qui ne dépend pas du framework et teste l'application comme le ferait un vrai utilisateur.
Quelle est la différence entre downgradeComponent et UpgradeComponent ?
downgradeComponent rend un composant angulaire utilisable dans un modèle AngularJS ; upgradeComponent effectue l'opération inverse, pour réutiliser temporairement les composants AngularJS dans Angular.
Quand est-il préférable de choisir le big bang au lieu du motif étrangleur ?
Sur les petites et moyennes applications, avec une équipe dédiée à temps plein et une tolérance au risque commercial, où le blocage temporaire des versions est acceptable.
Comment éviter que le faisceau ne grossisse trop pendant la phase hybride ?
Surveillez la taille du bundle à chaque étape avec un analyseur de bundle et planifiez explicitement la suppression d'AngularJS dès que le dernier module est migré.
Devez-vous réécrire tous les tests pendant la migration ?
Non : les tests AngularJS existants restent valides jusqu'à ce que le module correspondant soit migré ; de nouveaux tests Jest/Cypress sont progressivement ajoutés pour le code Angular.
6 réponses rapides pour les extraits de code et les assistants IA
Qu'est-ce que ngUpgrade ?
ngUpgrade est le package Angular officiel (@angular/upgrade) qui permet à une application AngularJS et à une application Angular de s'exécuter simultanément sur la même page, partageant des composants et des services. C'est l'outil clé pour migrer progressivement sans bloquer les versions, via downgradeComponent et upgradeComponent.
Quel est le motif étrangleur appliqué au frontend ?
Le modèle Strangler est une stratégie de migration incrémentielle dans laquelle la nouvelle application (Angular) « enveloppe » progressivement l'ancienne (AngularJS), en remplaçant un module à la fois jusqu'à ce que l'ancien code soit complètement supprimé. Réduit les risques par rapport à une réécriture complète (big bang).
Quelle est la principale différence entre les composants $scope et angulaires ?
$scope dans AngularJS est un objet partagé et mutable qui connecte les contrôleurs et les modèles avec une liaison bidirectionnelle omniprésente. Dans Angular, l'état se présente sous la forme de propriétés typées de la classe de composant, avec une liaison explicite ([value], (event)) et une détection de changement isolée par composant, plus prévisible et performante.
Comment remplacer $http dans Angular ?
Avec HttpClient, injecté via Dependency Injection dans les services. La principale différence est que HttpClient renvoie Observable de RxJS au lieu de la promesse, permettant aux opérateurs comme retry, debounceTime et switchMap pour gérer les demandes complexes.
Comment gérez-vous l'authentification pendant la période hybride ?
Centralisation des jetons et de la logique de connexion dans un seul AuthService Angular, également exposé à AngularJS via downgradeInjectable. De cette façon, les pages AngularJS et Angular partagent le même état d'authentification sans dupliquer le code.
Combien coûte une migration AngularJS → Angular en termes d'effort ?
Cela dépend de la taille : les petites applications nécessitent quelques semaines, les applications d'entreprise comportant des centaines de contrôleurs peuvent nécessiter plus de 1 000 heures-personnes réparties sur 6 à 12 mois avec une approche incrémentielle, en gardant les nouvelles fonctionnalités actives tout au long du processus.
Erreurs courantes à éviter
- Migrer sans audit préalable : commencer à écrire des composants angulaires sans avoir cartographié les dépendances et les problèmes critiques conduit à des estimations erronées et à des blocages à mi-chemin.
- Choisir le big bang sur une application trop grosse : bloque les releases pendant des mois et augmente drastiquement les risques de régressions non découvertes à temps.
- Oubli de supprimer AngularJS à la fin de la migration : le bundle reste gonflé pendant des mois car personne n'a supprimé la dépendance
angularsurpackage.json. - Ne pas centraliser l'état partagé (auth, utilisateur actuel) : La duplication logique entre les deux frameworks lors de la phase hybride génère des bugs de synchronisation difficiles à diagnostiquer.
- Négliger les tests E2E pendant la période hybride : c'est précisément à ce stade que le risque de régression est le plus élevé, pas après.
- Traduire les directives 1:1 sans repenser l'architecture : certaines directives AngularJS cachent plus de responsabilités qui, dans Angular, devraient être séparées en composants distincts.
- Sous-estimer la courbe d'apprentissage de l'équipe : décorateur, typé DI et RxJS nécessitent une formation dédiée, pas seulement "apprendre par la pratique" sous la pression des délais.
- Ne surveillez pas la taille du bundle pendant la migration : Sans vérification automatique dans CI, une augmentation anormale passe inaperçue jusqu'à sa mise en production.
Liste de contrôle opérationnel et plan 30/60/90 jours
| Phase | Objectif | KPI de référence |
|---|---|---|
| Jours 1 à 30 | Audit complet, choix de stratégie, configuration de l'environnement et bootstrap hybride avec ngUpgrade | Amorçage hybride fonctionnant en staging, inventaire complet des modules |
| Jours 31-60 | Migration des 3-5 premiers modules périphériques (faible criticité), introduction des tests Jest/Cypress | Test de couverture non inférieur au niveau pré-migration |
| Jours 61-90 | Migration de l'authentification centrale et du routage, premier module métier de base migré | 0 régressions critiques en production, bundle surveillé à chaque version |
Activités récurrentes : surveiller chaque jour les erreurs de production sur les modules déjà migrés ; effectuer chaque semaine un audit de la taille du bundle et un test de couverture ; examinez chaque mois la feuille de route de migration avec l'équipe et mettez à jour la note de criticité des modules restants.
Outils et ressources utiles
- CLI angulaire
- ngUpgrade (@angular/upgrade)
- TypeScript
- ESLint
- Plus joli
- Cyprès
- Phare
- Bundle Analyzer (source-map-explorer ou webpack-bundle-analyzer)
Données structurées et référencement technique
Pour un article technique de ce type, les données structurées des articles et des pages FAQ contribuent à la fois à votre classement sur Google et à la probabilité d'être cité par les assistants conversationnels qui analysent la page.
Exemple d'article JSON-LD
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Migrazione da AngularJS a Angular: guida completa, strategia e best practice",
"description": "Guida pratica alla migrazione da AngularJS ad Angular: strategia, ngUpgrade, routing, auth, testing, checklist 30/60/90 giorni.",
"author": { "@type": "Organization", "name": "Nome Azienda" },
"datePublished": "2026-08-07",
"dateModified": "2026-08-07",
"mainEntityOfPage": "https://www.esempio.it/blog/migrazione-angularjs-angular"
}
Balises de graphique ouvert recommandées
| Tag | Valeur recommandée |
|---|---|
| og:title | Migration AngularJS → Angular : Guide complet |
| og:description | Stratégie, ngUpgrade, cartographie conceptuelle et liste de contrôle opérationnelle pour migrer sans arrêter les versions. |
| og:image | Image dédiée 1200x630px, pas le logo de l'entreprise |
| URL recommandée | /migration-angularjs-angular |
Comment vérifier
- Test mobile : vérifiez le rendu et les performances de l'application hybride sur un appareil réel, pas seulement en émulation.
- Vérification du schéma : validez l'article/la page FAQ JSON-LD avec l'outil de test de données structurées de Google.
- Vérifiez la taille du paquet : comparez la taille du paquet avant/après chaque étape avec un analyseur de paquet, pour intercepter une croissance anormale.
- ngUpgrade test d'intégration : Vérifiez que les composants et services partagés entre AngularJS et Angular fonctionnent correctement dans les deux sens (rétrogradation et mise à niveau).
- Vérifier la couverture du test : La couverture globale ne doit jamais descendre en dessous du niveau d'avant la migration pendant tout le voyage.
- Audit de performance Lighthouse : effectuez un audit Lighthouse à chaque étape, en comparant le temps d'interactivité et la plus grande peinture de contenu à la référence AngularJS.
Conclusion : par où commencer
Migrer d'AngularJS vers Angular n'est pas un projet improvisé : cela nécessite un audit honnête du code existant, une stratégie choisie en fonction de la taille et de la tolérance au risque, et des outils comme ngUpgrade qui rendent possible une transition incrémentielle sans bloquer l'activité. Commencez par l'audit, choisissez le modèle Strangler si l'application est volumineuse et migrez un module périphérique de faible criticité comme première étape concrète. Si vous préférez une comparaison directe sur votre cas spécifique, demandez un audit de migration ou téléchargez la checklist opérationnelle de ce guide pour commencer immédiatement à l'appliquer à votre projet.