こんにちは、フロントエンドエンジニアの沖です。 セーフィーには2022年1月にジョインし映像閲覧WebアプリであるSafie Viewer(以下Viewer)の開発を担当しています。
今回は、Viewerで利用しているフレームワークであるAngularのバージョンアップを9月末のリリース時に行ったのでその話をしたいと思います。
Viewerについて
セーフィーのクラウド録画サービスは、カメラで撮影した映像をクライアントアプリケーションを用いて閲覧することが出来ます。クライアントアプリケーションはいくつかありますがその一つがViewerです。ViewerはWebブラウザで閲覧可能なWebアプリケーションとして提供されています。
機能としては、普通に映像が閲覧できる基本機能の他に複数のカメラの映像を同時に閲覧できるマルチビューアーだったりユーザーが独自の画面を作成し、閲覧できるダッシュボードだったり様々な機能があります。
このViewerでは下記の技術が導入されています。
- 言語:typescript
- フレームワーク:Angular
- CSS:Tailwind CSS
- Code Formatter:prettier
- Lint:eslint
この度Viewerで利用しているフレームワークであるAngularを13から14へアップデートしました。
Viewerのアップデートサイクル
Angularは約半年ごとにメジャーリリースが行われるので、セーフィーでは原則として新しいバージョンがリリースされてから1~2か月を目途にバージョンアップを行います。 Angular 13の時のIEサポート終了などインパクトが大きい変更がある場合にはリリーススケジュールが前後する可能性がありますが、出来るだけはやくバージョンアップできるようにしています。
マイナーバージョンについても随時Viewerのリリースサイクルに合わせてバージョンアップしています。 古いバージョンを使い続けることで安定性を担保するという考え方もありますが、最新バージョンに追従することで積極的に新しい機能を利用していくという面もセーフィーでは重要視しています。
今回のアップデートによる変更点
Angular 14の目玉と言ったらなんといってもStandalone Components(Standalone APIs)とTyped formsですね。
Standalone Components
Standalone Componentsはmoduleを仲介しなくても直接呼び出せるcomponentで、今までmodule内で定義されていた暗黙的な依存がなくなるということで注目されている新機能です。
今まではNgModuleを定義してその中にcomponentと一緒に使うモジュール群をimportsに入れて定義しなければいけませんでしたが、NgModuleを介さずに直接componentを呼び出すことが出来るようになりました。
@Component({ selector: ‘sf-test’, template: ‘<div>standalone test</div>’, standalone: true // ここをtrueにすることでstandaloneとして扱うことが可能 }) export class TestComponent {}
standaloneコンポーネントは直接呼び出せる一方で依存しているmoduleのimportを自身で行う必要があるため全てをstandaloneにするというより要所要所で利用していくのがいい印象です。
Typed Forms
Typed formsはReactive Formsのvalueの型を指定できる機能です。 初期値を入れてFormControlを作成、もしくは型を指定してFormControlを定義しておくとそのControlのsetValueを呼ぶ際の型チェックやそのControlが属しているFormGroupのvalueChangesで型をつけることが出来ます。
const a = new FormControl(‘test’); a.setValue(true); // こういった場合にエラーとなってくれます。
地味な変更点
angular.jsonでのdefault projectが廃止になりました。 これにより今後ng buildやng serveの際に必ずprojectを指定する必要があります。
アップデート作業について
今回のアップデートは、あまり破壊的変更はなく新機能の追加がメインだったのでng updateで問題なくアップデートすることが出来ました。
default projectの部分は多くの人が作業が必要になるかと思われますが、それも大きな修正は必要ないため今回のアップデートは比較的気軽に出来るのではないかと思います。
今後試してみたい新機能
Standalone Components
セーフィーのアプリケーションの性質上、ユーザーによって同じカメラを所有していたとしても利用できる機能が異なる場合があります。 現状もそのような場合にはLazyLoadingを利用して機能が必要のないユーザーに余計なモジュールをロードさせないような仕組みがあるのですが、その一部をStandalone Componentsに置き換えることで見通しのいいコードにできるのではないかと考えています。Developer previewが明けたら本格的に導入を考えたいと思います。
runInContext(Angular 14.1系)
こちらは14.1の機能ですが、EnvironmentInjectorにrunInContextというメソッドが追加されました。この機能はrunInContextの中ではinjectメソッドを使うことによりEnvironmentInjectorでinject可能なサービスを取り出すことが出来るというものです。 今までは、DIで取り出すサービスを用いた処理は、InjectableなクラスやComponentなどAngularの管理下のクラス内で記述する必要がありましたが、これを用いることでサービスを用いたビジネスロジックもfunctionとして外に持たせることが可能となります。
const test = function() { const testService = inject(TestService); // testはただのfunctionですがこの中でinject出来ます。 } envirionmentInjector.runInContext(() => { test(); });
ビジネスロジックを外に出せるとテストの観点でも再利用の観点でもメリットが大きいので是非こちらは今後採用していこうと思っています。
まとめ
今回のAngularアップデートでは破壊的変更はあまりないものの新しい魅力的な機能が多数追加されているので、積極的にそれらを取り入れて使いやすく拡張性の高いアプリケーションにしていきたいと思っています。 フレームワークアップデートは場合によってはコストがかかる場合もありますが、保守性の向上やアプリケーションの最適化のためにも素早い追従が重要であると考えています。