关于 angular-migration
angular-migration 是面向将 AngularJS 应用迁移到 Angular 的技能,涵盖整体重写、渐进迁移与混合运行,并提供组件、服务、依赖注入和路由迁移指导。
主要功能
- 01整体、增量和垂直切片迁移方案
- 02AngularJS 与 Angular 混合运行
- 03控制器和指令转为组件
- 04服务与依赖注入迁移
- 05路由系统迁移
适用场景
- 01规划小型应用整体重写
- 02大型应用按功能逐步迁移
- 03将 AngularJS 指令改造为 Angular 组件
- 04更新服务、依赖注入和路由
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ wshobson/ agents --skill angular-migration安装后在 Claude Code 中输入/angular-migration确认已加载。
附带文件references/details.md
详细介绍
Angular 迁移
掌握从 AngularJS 到 Angular 的迁移,包括混合应用、组件转换、依赖注入变更以及路由迁移。
何时使用本技能
- 将 AngularJS(1.x)应用迁移到 Angular(2+)
- 运行 AngularJS/Angular 混合应用
- 将指令转换为组件
- 现代化依赖注入
- 迁移路由系统
- 升级到最新的 Angular 版本
- 实施 Angular 最佳实践
迁移策略
1. 大爆炸式(完全重写)
- 用 Angular 重写整个应用
- 并行开发
- 一次性切换
- 最适合: 小型应用、全新项目
2. 增量式(混合方案)
- 让 AngularJS 和 Angular 并行运行
- 逐个功能迁移
- 使用 ngUpgrade 实现互操作
- 最适合: 大型应用、持续交付
3. 垂直切片
- 完整迁移一个功能
- 新功能用 Angular,旧功能在 AngularJS 中维护
- 逐步替换
- 最适合: 中型应用、功能边界清晰
混合应用搭建
// main.ts - Bootstrap hybrid app
import { 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 });
});
// app.module.ts
import { 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
}
}
组件迁移
AngularJS 控制器 → Angular 组件
// Before: AngularJS controller
angular
.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);
};
});
// After: Angular component
import { 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 指令 → Angular 组件
// Before: AngularJS directive
angular.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>
`,
};
});
// After: Angular component
import { 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>
服务迁移
// Before: AngularJS service
angular.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);
},
};
});
// After: Angular service
import { 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);
}
}
依赖注入变更
降级 Angular → AngularJS
// Angular service
import { Injectable } from "@angular/core";
@Injectable({ providedIn: "root" })
export class NewService {
getData() {
return "data from Angular";
}
}
// Make available to AngularJS
import { downgradeInjectable } from "@angular/upgrade/static";
angular.module("myApp").factory("newService", downgradeInjectable(NewService));
// Use in AngularJS
angular.module("myApp").controller("OldController", function (newService) {
console.log(newService.getData());
});
升级 AngularJS → Angular
// AngularJS service
angular.module('myApp').factory('oldService', function() {
return {
getData: function() {
return 'data from AngularJS';
}
};
});
// Make available to Angular
import { 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());
}
}
路由迁移
// Before: AngularJS routing
angular.module("myApp").config(function ($routeProvider) {
$routeProvider
.when("/users", {
template: "<user-list></user-list>",
})
.when("/users/:id", {
template: "<user-detail></user-detail>",
});
});
// After: Angular routing
import { 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 {}
其他模式和模板
更详细的模板和完整示例位于 references/details.md。阅读该文件以获取完整的模式库。
评论
支持 Markdown