すっかり社内では Angular アップデート芸人と化している私ですが、
今回は Angular 16 から 17 へのアップデート時に走る angular/core
に関するマイグレーションの中身を軽く眺めてみます。
いや、17 から 18 じゃないんかーいという声もあるかと存じますが、それはまた別の記事でネタにさせていただきやす。
ちなみにアップデートを行う際は、上記公式アップデートガイドに沿って進めることを推奨します。Application complexity はプロジェクトによりますが、基本的には Advanced でいつも確認するようにしています。
また 16 から 17 へのアップデートに必要な node 等の条件は以下の通り
- node.js v18.13.0 以上
- TypeScript v5.2 以上
- Zone.js v0.14.x 以上
まあ、node 以外はng update
する際に勝手に更新してくれるので、前もってあげておくとかは別にしなくても実はいいのです。
本題
では、ng update
コマンドで angular/core
を 17系に更新していきましょう
ng update @angular/core@17 @angular/cli@17
@angular-eslint/schematics
や@angular-builders/jest
など、プロジェクトでお使いの @/angular 関連の依存関係によっては、ng update
してあげる対象が変わってくる場合がありますので、適宜ご確認ください。
以下、実行例(マイグレーション部分のみ抜粋)
** Executing migrations of package '@angular/core' **
❯ Angular v17 introduces a new control flow syntax that uses the @ and } characters.
This migration replaces the existing usages with their corresponding HTML entities.
UPDATE projects/app/src/shared/header/header.component.html (2707 bytes)
Migration completed (1 file modified).
❯ Updates `TransferState`, `makeStateKey`, `StateKey` imports from `@angular/platform-browser` to `@angular/core`.
Migration completed (No changes made).
❯ CompilerOption.useJit and CompilerOption.missingTranslation are unused under Ivy.
This migration removes their usage
Migration completed (No changes made).
❯ Updates two-way bindings that have an invalid expression to use the longform expression instead.
Migration completed (No changes made).
一つずつ見ていきましょ
対象のプロジェクトによってangular/cli
やcdk
のマイグレーションが含まれている場合がありますが、今回は core に絞った内容でお送りしています。
Angular v17 introduces a new control flow syntax that uses the @ and } characters.This migration replaces the existing usages with their corresponding HTML entities.
Angular 17 から新しく組み込みの制御フロー構文が追加されています。
ngIf
ngFor
ngSwitch
が @if
@for
@switch
で書けるようになったアレです。
なんかマイグレーションメッセージの冒頭だけ見ると、新しく組み込みの制御フローに置き換えてくれてそうに見えるのですが、実際そうではなく、今後新しい制御フロー構文で @
{
}
を使うので、HTMLテンプレート内で既に使われてるこれら文字列がある場合は、HTMLエンティティに置き換えるよという内容になっています。
極端な例ですが
<!-- Before -->
<p>@</p>
<!-- After -->
<p>@</p>
FYI:
ちなみに新しい制御フロー構文へのマイグレーションはちゃんと用意されているので、移行を考えている方はそちらを試してみることをおすすめする
Updates TransferState
, makeStateKey
, StateKey
imports from @angular/platform-browser
to @angular/core
.
これは書いてある通り、TransferState
makeStateKey
StateKey
のインポート元が@angular/platform-browser
から @angular/core
に変更されたので、これらのインポートを自動的に更新してくれます。
// Before
import { TransferState, makeStateKey, StateKey } from '@angular/platform-browser';
// After
import { TransferState, makeStateKey, StateKey } from '@angular/core';
CompilerOption.useJit and CompilerOption.missingTranslation are unused under Ivy.
Angular の Ivy コンパイラでは、CompilerOption.useJit
と CompilerOption.missingTranslation
が不要になったので、設定がある場合は自動で削除してくれます。
// Before
{
"compilerOptions": {
"useJit": true,
"missingTranslation": "ignore"
}
}
// After
{
"compilerOptions": {}
}
Updates two-way bindings that have an invalid expression to use the longform expression instead.
無効な式を持つ双方向バインディングを検出し、長形式の表現に置き換えます。これにより、バインディングの正確性と可読性が向上するとのこと。ここで言ってる無効な式とは、Angular のコンパイラが正しく解釈できない場合を指しているようです。
例を見ると、こんな感じに変換してくれるっぽいですね。
Before
import {Component} from '@angular/core';
@Component({
template: `<input [(ngModel)]="a && b"/>`
})
export class MyComp {}
After
import {Component} from '@angular/core';
@Component({
template: `<input [ngModel]="a && b" (ngModelChange)="a && (b = $event)"/>`
})
export class MyComp {}