Angular Migration

作者 wshobson46891e7e60da無授權條款收錄於 2026年10月8日更新於 2026年10月8日

Migrate from AngularJS to Angular using hybrid mode, incremental component rewriting, and dependency injection updates. Use when upgrading AngularJS applications, planning framework migrations, or modernizing legacy Angular code.

AI 產生的概覽

指導將 AngularJS 應用程式遷移至 Angular,涵蓋混合式應用程式、元件轉換、相依性注入與路由。

功能
此技能提供將 AngularJS(1.x)應用程式遷移至 Angular(2+)的說明與程式碼模式。內容涵蓋整體重寫、使用 ngUpgrade 的增量混合模式,以及垂直切片等遷移策略。它提供將控制器與指令轉換為元件、遷移服務、雙向調整相依性注入,以及改寫路由的前後對照範例。參考檔案包含更多範本與完整範例。
適用情境
適用於升級 AngularJS 應用程式、規劃框架遷移,或現代化改造舊版 Angular 程式碼時。也適合執行 AngularJS/Angular 混合式應用程式,或轉換指令、服務與路由的團隊。
執行需求
不隨附指令碼,僅為說明性內容。所述工作假定已有 AngularJS 與 Angular 專案及 Angular 升級模組等相關框架套件,但技能本身除代理外無需其他條件。

Angular Migration

Master AngularJS to Angular migration, including hybrid apps, component conversion, dependency injection changes, and routing migration.

When to Use This Skill

  • Migrating AngularJS (1.x) applications to Angular (2+)
  • Running hybrid AngularJS/Angular applications
  • Converting directives to components
  • Modernizing dependency injection
  • Migrating routing systems
  • Updating to latest Angular versions
  • Implementing Angular best practices

Migration Strategies

1. Big Bang (Complete Rewrite)

  • Rewrite entire app in Angular
  • Parallel development
  • Switch over at once
  • Best for: Small apps, green field projects

2. Incremental (Hybrid Approach)

  • Run AngularJS and Angular side-by-side
  • Migrate feature by feature
  • ngUpgrade for interop
  • Best for: Large apps, continuous delivery

3. Vertical Slice

  • Migrate one feature completely
  • New features in Angular, maintain old in AngularJS
  • Gradually replace
  • Best for: Medium apps, distinct features

Hybrid App Setup

typescript
// main.ts - Bootstrap hybrid appimport { platformBrowserDynamic } from "@angular/platform-browser-dynamic";import { UpgradeModule } from "@angular/upgrade/static";import { AppModule } from "./app/app.module";
platformBrowserDynamic()  .bootstrapModule(AppModule)  .then((platformRef) => {    const upgrade = platformRef.injector.get(UpgradeModule);    // Bootstrap AngularJS    upgrade.bootstrap(document.body, ["myAngularJSApp"], { strictDi: true });  });
typescript
// app.module.tsimport { NgModule } from "@angular/core";import { BrowserModule } from "@angular/platform-browser";import { UpgradeModule } from "@angular/upgrade/static";
@NgModule({  imports: [BrowserModule, UpgradeModule],})export class AppModule {  constructor(private upgrade: UpgradeModule) {}
  ngDoBootstrap() {    // Bootstrapped manually in main.ts  }}

Component Migration

AngularJS Controller → Angular Component

javascript
// Before: AngularJS controllerangular  .module("myApp")  .controller("UserController", function ($scope, UserService) {    $scope.user = {};
    $scope.loadUser = function (id) {      UserService.getUser(id).then(function (user) {        $scope.user = user;      });    };
    $scope.saveUser = function () {      UserService.saveUser($scope.user);    };  });
typescript
// After: Angular componentimport { Component, OnInit } from "@angular/core";import { UserService } from "./user.service";
@Component({  selector: "app-user",  template: `    <div>      <h2>{{ user.name }}</h2>      <button (click)="saveUser()">Save</button>    </div>  `,})export class UserComponent implements OnInit {  user: any = {};
  constructor(private userService: UserService) {}
  ngOnInit() {    this.loadUser(1);  }
  loadUser(id: number) {    this.userService.getUser(id).subscribe((user) => {      this.user = user;    });  }
  saveUser() {    this.userService.saveUser(this.user);  }}

AngularJS Directive → Angular Component

javascript
// Before: AngularJS directiveangular.module("myApp").directive("userCard", function () {  return {    restrict: "E",    scope: {      user: "=",      onDelete: "&",    },    template: `      <div class="card">        <h3>{{ user.name }}</h3>        <button ng-click="onDelete()">Delete</button>      </div>    `,  };});
typescript
// After: Angular componentimport { Component, Input, Output, EventEmitter } from "@angular/core";
@Component({  selector: "app-user-card",  template: `    <div class="card">      <h3>{{ user.name }}</h3>      <button (click)="delete.emit()">Delete</button>    </div>  `,})export class UserCardComponent {  @Input() user: any;  @Output() delete = new EventEmitter<void>();}
// Usage: <app-user-card [user]="user" (delete)="handleDelete()"></app-user-card>

Service Migration

javascript
// Before: AngularJS serviceangular.module("myApp").factory("UserService", function ($http) {  return {    getUser: function (id) {      return $http.get("/api/users/" + id);    },    saveUser: function (user) {      return $http.post("/api/users", user);    },  };});
typescript
// After: Angular serviceimport { Injectable } from "@angular/core";import { HttpClient } from "@angular/common/http";import { Observable } from "rxjs";
@Injectable({  providedIn: "root",})export class UserService {  constructor(private http: HttpClient) {}
  getUser(id: number): Observable<any> {    return this.http.get(`/api/users/${id}`);  }
  saveUser(user: any): Observable<any> {    return this.http.post("/api/users", user);  }}

Dependency Injection Changes

Downgrading Angular → AngularJS

typescript
// Angular serviceimport { Injectable } from "@angular/core";
@Injectable({ providedIn: "root" })export class NewService {  getData() {    return "data from Angular";  }}
// Make available to AngularJSimport { downgradeInjectable } from "@angular/upgrade/static";
angular.module("myApp").factory("newService", downgradeInjectable(NewService));
// Use in AngularJSangular.module("myApp").controller("OldController", function (newService) {  console.log(newService.getData());});

Upgrading AngularJS → Angular

typescript
// AngularJS serviceangular.module('myApp').factory('oldService', function() {  return {    getData: function() {      return 'data from AngularJS';    }  };});
// Make available to Angularimport { InjectionToken } from '@angular/core';
export const OLD_SERVICE = new InjectionToken<any>('oldService');
@NgModule({  providers: [    {      provide: OLD_SERVICE,      useFactory: (i: any) => i.get('oldService'),      deps: ['$injector']    }  ]})
// Use in Angular@Component({...})export class NewComponent {  constructor(@Inject(OLD_SERVICE) private oldService: any) {    console.log(this.oldService.getData());  }}

Routing Migration

javascript
// Before: AngularJS routingangular.module("myApp").config(function ($routeProvider) {  $routeProvider    .when("/users", {      template: "<user-list></user-list>",    })    .when("/users/:id", {      template: "<user-detail></user-detail>",    });});
typescript
// After: Angular routingimport { NgModule } from "@angular/core";import { RouterModule, Routes } from "@angular/router";
const routes: Routes = [  { path: "users", component: UserListComponent },  { path: "users/:id", component: UserDetailComponent },];
@NgModule({  imports: [RouterModule.forRoot(routes)],  exports: [RouterModule],})export class AppRoutingModule {}

Additional patterns and templates

More detailed templates and worked examples live in references/details.md. Read that file for the full pattern library.

來源與署名

來源:wshobson/agents位於plugins/framework-migration/skills/angular-migration提交46891e7

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架