🐈

Angular20アップデート雑感(マニアック路線)

に公開

Angular20がリリースされました。区切りでこれが大きく変わった!ということはなく、これまで通りに開発が進んでいます。具体的な内容はこちらをご覧ください。

https://blog.angular.dev/announcing-angular-v20-b5c9c06cf301
https://www.youtube.com/watch?v=FcDamOe1qxA

開発者視点であったり、技術的な内容はこれらに譲るとして、この記事では私がアップデートしてて面白いなと思ったトピックを紹介します。

control-flow-migration

ng update でアップデートをかけたら、以下のオプショナルマイグレーションがでてきました。いつも思うんですが、「オプショナルマイグレーション」といってもignoreの選択肢ない状態で後続のマイグレーションがわからないので、あまりオプショナル感ないですよね。笑

** Optional migrations of package '@angular/core' **

This package has 1 optional migration that can be executed.
Optional migrations may be skipped and executed after the update process, if preferred.

 Select the migrations that you'd like to run (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
❯◯ [control-flow-migration] Converts the entire application to block control flow syntax.

これで実質、Angular20以降のプロジェクトからは NgIf NgFor NgSwitch といった以前の構文からは一掃されることになりました。 deprecated がついたので、1年後のv22以降にこれらのAPIはなくなることになります。個人的に、某OSSプロジェクトが「後方互換」を名乗ってAPIが無限に増え続けて開発的には負債と化しているのをみているので、Angularのこの

  • 新代替APIをだす
  • コミュニティからヒアリング
  • 自動マイグレーションで旧APIをユーザプロジェクトから削除
  • deprecatedに
  • 1年後にプロジェクトから削除して負債を解消

というサイクルは大好きです。新陳代謝しながら改善されていくのは、いわゆる「枯れてるからいい」層とは対局のところにありますが、追随するだけでプロジェクト自体も改善されていくのは「フレームワーク」感あっていいですよね。

builderが @angular-devkit/build-angular から @angular/build に

追ってみたら、最初の @angular/build のコミットはこれですね。

https://github.com/angular/angular-cli/commit/810d213e1813dd01620173f5f999dca7bccf8ea1

@angular-devkit/build-angular はWebPackベースの後方互換もサポートするけど、こっちは esbuild/Vite ベースのビルドだけになるようです。 @angular-devkit/build-angularpackage.json をみてみると、 dependencies@angular/build があるので、 @angular-devkit/build-angular は後方互換用としての役割になるようですね。

Angularに沿ってマイグレーションを重ねてるユーザでしたら、v19でesbuildがデフォルトになっているので( @angular-devkit/build-angular:application )、ここはあまり気にしなくてよさそうです。一点だけ、 karma.config.js でテストランナーの設定を行っており、プラグインに @angular-devkit/build-angular/plugins/karma を使っているユーザがいれば、このプラグインは @angular/build から生えていないので、@angular-devkit/build-angular も併用して利用する必要があります。

後方互換のない軽量なbuilderに変更されたぐらいの理解でよさそうです。

ライブラリの出力に元ファイルの d.ts を含めなくなった

Angular19までは、ライブラリの出力( dist )内には、ビルド後ファイル以外にも、型定義ファイルがプロジェクトの構造のまま残っていました。例えば、私の scroll-strategies ライブラリのAngular19での出力です。

dist/scroll-strategies/
├── fesm2022/
│   ├── rdlabo-ngx-cdk-scroll-strategies.mjs
│   └── rdlabo-ngx-cdk-scroll-strategies.mjs.map
├── lib/
│   ├── dynamic-size-virtual-scroll-strategy.d.ts
│   └── dynamic-size-virtual-scroll.service.d.ts
├── index.d.ts
├── package.json
├── public-api.d.ts
└── README.md

もともとのプロジェクトには src/lib/dynamic-size-virtual-scroll-strategy.tssrc/lib/dynamic-size-virtual-scroll.service.ts があるので、 src の中身がフラットに展開されて、 d.ts が格納されている形ですね。 これが、Angular20で、以下のようになりました。

dist/scroll-strategies/
├── fesm2022/
│   ├── rdlabo-ngx-cdk-scroll-strategies.mjs
│   └── rdlabo-ngx-cdk-scroll-strategies.mjs.map
├── index.d.ts
├── package.json
└── README.md

lib/dynamic-size-virtual-scroll-strategy から型情報をインポートするようなことをしていなければ意識することもないのですが(ついでにいうとビルド設定次第なところはありますし)、変更されています。これに関するIssueは Flatten type definitions to a single *.d.ts file #139
ですね。

ちなみに、ライブラリも @angular-devkit/build-angular:ng-packagr でのビルドから、 @angular/build:ng-packagr でのビルドになりました。

Experimental APIの変更

Resources APIにいくつか破壊的変更がありました。
https://zenn.dev/rdlabo/articles/ff0bc7de29bd65

また、 provideExperimentalZonelessChangeDetectionprovideZonelessChangeDetection にリネームされたり。実験中のAPIなので、より使いやすく直感的になっていくのいいですよね。

まとめ

Angular2から使い続けていますが、最近でいうとSignalの登場から、Signal-basedでの設計、Zonelessと、確実にフレームワークとして使いやすくなっていってます。
何よりも、突然の破壊的変更に振り回されず、公式のガイド通りにアップデートを続けていれば自然と最新の設計に追いつける安心感があります。派手さはないけれど、堅実に進化し続けるフレームワークなので、プロダクトのベースとしてとても助かっています。

それではまた。

Discussion