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 从公开仓库中收录这些内容。

举报或申请下架