园子博客后台 Angular 升级:手工迁移至 Standalone Component

最近在将园子博客后台的前端框架从 angular 15 升级至 angular 19,这边博文记录的是迁移至 Standalone Component 的过程。

之前尝试使用 angular 19 提供的迁移命令自动迁移,但迁移失败,详见 https://q.cnblogs.com/q/150498

ng g @angular/core:standalone

改为手动迁移,记录一下迁移过程。

删除标记与 NgModule 文件

  • 删除所有 standalone: false,一共 198
  • 删除所有 NgModule 文件,一个 84 个文件
find . -name *.module.ts -exec git rm {} \;
  • 恢复测试中使用的 NgModule 文件 testing.module.ts

迁移至 standalone bootstrapping api

  • 修改 main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';

bootstrapApplication(AppComponent, appConfig)
    .catch((err) => console.error(err));
  • 创建 app.config.ts 文件并将 app.module.ts 中的 providers 迁移过来
export const appConfig: ApplicationConfig = {
    providers: [
        provideHttpClient(withFetch()),
        provideAnimations(),
        provideZoneChangeDetection(
            {
                eventCoalescing: true
            }),
        provideRouter(
            routes,
            withRouterConfig({
                onSameUrlNavigation: 'reload'
            }),
            withPreloading(NoPreloading),
            withViewTransitions()
        ),
        NzModalService,
        LoggerService,
        // ...
    ]
};
  • 恢复 app-routing.module.ts 文件并重命名为 app.routes.ts
git checkout HEAD~1 app-routing.module.ts
git mv app-routing.module.ts app.routes.ts
  • 处理 app.routes.ts 中通过 loadChildren 加载 NgModule 的代码
loadChildren: () => import('./pages/posts/posts.module').then(m => m.PostsModule)
  • 将 posts.module.ts 并转换为 posts.routes.ts
git checkout HEAD~1 ./pages/posts/posts.module.ts
git mv ./pages/posts/posts.module.ts ./pages/posts/posts.routes.ts
  • 修改 posts.routes.ts,改为 export const routes, 删除 NgModule 部分代码,修改路由部分代码
export const POSTS_ROUTES: Routes = [
    {
        path: '',
        component: PostMainComponent,
    }
]
  • 修改 app.routes.ts 中对应的 loadChildren 代码
loadChildren: () => import('./pages/posts/posts.routes').then(m => m.POSTS_ROUTES)
  • 在 app.config.ts 中添加 onSameUrlNavigation 与 preloadingStrategy 配置
export const appConfig: ApplicationConfig = {
    providers: [
        provideZoneChangeDetection(
            {
                eventCoalescing: true
            }),
        provideRouter(
            routes,
            withRouterConfig({
                onSameUrlNavigation: 'reload'
            }),
            withPreloading(NoPreloading)
        ),
        provideHttpClient(withFetch()),
    ]
};

添加 import

近 200 个 component 需要一个一个 component 添加所需的 import,这是迁移中工作量最大的部分,即使只是用到了 *ngIf 或者 [ngClass], 也要添加对应的 import,详见 https://q.cnblogs.com/q/151533

解决 ViewChild 的问题

详见博问:迁移到 Standalone Component 后 ViewChild 无法正常工作

处理 imports 中漏添加 Directive 的问题

一个 standalone component 的模板中用了某个 directive,如果没有在 imports 中添加,build 与运行是都不会报错,只是这个 directive 没有被执行。

参考资料

posted @ 2025-01-09 09:46  dudu  阅读(6)  评论(0编辑  收藏  举报