LoginSignup
0
1

Angular12+Nxで作成されたWEBサイトをAngular17にアップデート

Posted at

はじめに

Angular12で作成されたWEBサイトを最新(Angular17)にアップデートする機会があったので、ソースと手順を残しておく。
Nxを使ったモノレポ構成だったこともあり、簡単にはいかなかった。

以下のAngular12のソースを17にバージョンアップする。
Angular + Nest Example2

Angular CLI: 12.2.11
Node: 16.12.0
Package Manager: npm 8.1.0

npm-check-updatesを使用した更新(失敗)

まずはnpm-check-updatesを試してみる。
ncu -uでpackage.jsonをまとめて最新にする。

PS C:\Work\git\angular-nest-example2> ncu -u                        
Upgrading C:\Work\git\angular-nest-example2\package.json
[====================] 62/62 100%

 @angular-devkit/build-angular            ~12.2.0  →  ~17.0.7
 @angular-eslint/eslint-plugin            ~12.3.0  →  ~17.1.1
 @angular-eslint/eslint-plugin-template   ~12.3.0  →  ~17.1.1
・
・中略
・
 typescript                                ~4.3.5  →   ~5.3.3
 zone.js                                  ~0.11.4  →  ~0.14.2

Run npm install to install new versions.

・・・何となく無理っぽい気はするけど、まあダメもとでやってみるか。
npm installだと依存関係エラーが出たので、とりあえずnpm install --legacy-peer-depsで強引に進め、インストールは成功。
だが、実行時に、以下のエラーが発生。

image.png

Nxの構成が大きく変わっているらしく、そのあたりをなんとかする必要がありそう。

Nxコマンドを使用した更新(失敗)

Nxのコマンドにも自動更新があるので、今度はこちらを試してみる。
Automate Updating Dependencies | Nx

まずはnx migrate latestコマンドでモジュールのバージョンを更新。これは成功した。
またnpm install --legacy-peer-depsで強引にモジュールをインストールする。

次にnx migrate --run-migrationsを実行したが、失敗。

 >  NX   Failed to run block-template-entities from @angular/core. This workspace is NOT up to date!
 >  NX   import_typescript3.default.getDecorators is not a function

ネットの情報をもとにnx.jsonproject.jsonなどを変更してみたが、どうにも解決できず・・・。
諦めて、Nxのプロジェクトを1から作り直すことにする。

新規Nxプロジェクトの再作成

まずはnestの環境(api)を生成。

npx create-nx-workspace@latest --preset nest --name angular-nest-example3 --appName api --nxCloud true

作成されたプロジェクトフォルダに移動して、angularの環境(web)を生成。

npm install @nrwl/angular
nx generate @nrwl/angular:application --name web

とりあえずこれで「api」と「web」のフォルダが作成され、nx serve api、nx serve webでそれぞれ起動できる。

ソースコピー

変更元のソースを新環境にコピーする。
apps\api\srcapps\api\srcの配下は丸ごと上書きでいいはず。

package.jsonは、scripts部分は上書き。
dependenciesなどは、この後コマンドでモジュール追加していく。

その他、tsconfig.jsonなどは、差分を見比べて必要な部分をマージしていく。

モジュールの追加

変更元のpackage.jsonを参考に、必要なモジュールを追加していく。

npm install @angular/cdk --legacy-peer-deps
npm install @angular/material --legacy-peer-deps
・
・
・
以下略

エラーの回避

npm startで起動しようとすると、大量のエラーが出てきた・・・一つずつ回避していく。

relativeLinkResolution

relativeLinkResolutionの定義は、Angular15あたりで不要になったらしい。

Error: apps/web/src/app/app-routing.module.ts:19:46 - error TS2345: Argument of type '{ relativeLinkResolution: string; }' is not assignable to parameter of type 'ExtraOptions'.
  Object literal may only specify known properties, and 'relativeLinkResolution' does not exist in type 'ExtraOptions'.

19     imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],

↓ 単純に削除すればOK。

imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],

imports: [RouterModule.forRoot(routes)],

entryComponents

entryComponentsの定義もAngular15あたりで不要になったらしい。

Error: apps/web/src/app/app.module.ts:113:5 - error TS2345: Argument of type '{ declarations: (typeof AppComponent | typeof SimpleDialogComponent | typeof TableDialogComponent | typeof ProgressSpinnerComponent)[]; imports: (typeof BrowserModule | ... 1 more ... | ModuleWithProviders<...>)[]; providers: (typeof HttpRequestInterceptor | ... 1 more ... | { ...; })[]; bootstrap: (typeof AppCompon...' is not assignable to parameter of type 'NgModule'.
  Object literal may only specify known properties, and 'entryComponents' does not exist in type 'NgModule'.

113     entryComponents: [
        ~~~~~~~~~~~~~~~

↓ これも単純に削除すればOK。

@NgModule({
    declarations: [
        AppComponent,
        SimpleDialogComponent,
        TableDialogComponent,
        ProgressSpinnerComponent,
    ],
    imports: [
        BrowserModule,

・ 中略

    bootstrap: [AppComponent],
    // entryComponents: [       ★←削除。
    //     SimpleDialogComponent,
    //     TableDialogComponent,
    // ],
})
export class AppModule {}

Theming機能

Theming機能については、Angular15で大幅に仕様が変わったらしい。
インポートの時点でエラーが出ている。

./apps/web/src/assets/styles/styles.scss?ngGlobalStyle - Error: Module build failed (from ./node_modules/@angular-devkit/build-angular/node_modules/mini-css-extract-plugin/dist/loader.js):
HookWebpackError: Module build failed (from ./node_modules/@angular-devkit/build-angular/node_modules/sass-loader/dist/cjs.js):
Can't find stylesheet to import.
  ╷
4 │ @import '~@angular/material/theming';
  │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

それぞれ、以下のように変更する。

@import '~@angular/material/theming';
@include mat-core();
↓↓↓
@use 'node_modules/@angular/material' as mat;
@include mat.core();

以下、darkテーマを変更したときの修正例。
メソッド名などが微妙に変わっているが、変更後のメソッドに書き直すだけでだいたいいけた。

$dark-primary:  mat-palette($mat-blue-grey);
$dark-accent:   mat-palette($mat-amber, A200, A100, A400);
$dark-warn:     mat-palette($mat-deep-orange);
↓↓↓
$dark-primary:  mat.define-palette(mat.$blue-grey-palette);
$dark-accent:   mat.define-palette(mat.$amber-palette, A200, A100, A400);
$dark-warn:     mat.define-palette(mat.$deep-orange-palette);
$dark-theme: mat-dark-theme($dark-primary, $dark-accent, $dark-warn);
↓↓↓
$dark-theme: mat.define-dark-theme((
    color: (
        primary: $dark-primary,
        accent: $dark-accent,
        warn: $dark-warn,
    )
));
.dark-theme {
    @include angular-material-theme($dark-theme);
}
↓↓↓
.dark-theme {
    @include mat.all-component-themes($dark-theme);
}
.dark-theme-color {
    background-color : mat-color($dark-background-palette, background)!important;
    color: mat-color($dark-foreground-palette, text)!important;
}
↓↓↓
.dark-theme-color {
    background-color : mat.get-color-from-palette(mat.$dark-theme-background-palette, background)!important;
    color: mat.get-color-from-palette(mat.$dark-theme-foreground-palette, text)!important;
}

mat.$blue-grey-paletteなどは、デフォルトで定義されているパレット。
定義の名称などは、以下に記載されている。
node_modules@angular\material\core\theming_palette.scss

定義済みのパレットの色などは、以下で確認できる。
https://m1.material.io/style/color.html#color-color-palette

その他

細かいデザインの修正

微妙にデザインが崩れているところがあるので、修正していく。
特に、Angular MaterialがMDC(Material Design Component)ベースに変更されたらしく、その影響で微妙なずれが発生している個所が多かった。
これも自動で更新するコマンドがあるようだが(参考「Migrating to MDC-based Angular Material Components」)、未確認。
一つ一つ個別に修正していく。

依存関係エラー対応

npm installで発生していた依存関係エラーを確認する。
どうやらangular-resize-eventというモジュールが最新では使えなくなっているらしい。
新しいバージョンも出ておらず、変わるライブラリも見当たらなかったので、ResizeObserverを使用する方法に書き直した。
これで--legacy-peer-depsしなくてもモジュールインストールできるようになった。

完成

これで、一通り元と同じ状態になったはず。
変更後のソースは以下の通り。
変更履歴つき。
Angular + Nest Example3

Angular CLI: 17.0.6
Node: 20.9.0
Package Manager: npm 10.1.0

結局は最初から作り直したほうが早いかも、というお話でした。
(特に一気に複数バージョンアップする場合は。)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1