SSTエンジニアブログ

SSTのエンジニアによるWebセキュリティの技術を中心としたエンジニアブログです。

新規サービスのフロントエンド技術選定 ~Angularをメインに据えてみたその後~

はじめに

どうも、SST研究開発部の小野里です。 弊社は去る10月末、EASMサービスのβ版をリリースいたしました。あれから約1ヶ月ちょっと、ありがたいことに様々なお客様に試用いただきご好評を頂いております。

www.securesky-tech.com

思えば社内での開発開始からおよそ9ヶ月近くが経ったでしょうか。私は開発の割と初期から参加しており、主にフロントエンドの技術選定から実装までフロントエンド全般を担当していました(最近は開発メンバーが増えたのもあって私一人ではなくなりましたし、私もバックエンド等もやるようになりました)。当初はかなり手探り状態の中で進めてきた感もあるプロジェクトでしたが、いよいよ正式リリースを来月に控えたこのタイミングで、最初の技術選定の際にどんなことを考えていたか、実際にひとまずの完成が見えてきてどうだったかを振り返ってみようと思います。

※本記事における意見は、筆者の個人的な意見であり、所属団体や関与するプロジェクト等の意見を代表するものではありません。

技術選定

弊社EASMサービス(以下、EASMと呼びます)のフロントエンドでは、主に以下のような技術を使っています。

以下、それぞれについて何故この選択をしたのか振り返ってみます。

フレームワーク:Angular

angular.jp

EASMではメインのフレームワークにAngularを使用しています。日本での主流はReactじゃないの?と思われる方もいらっしゃるでしょうし、実際私もReactの経験は多少あれど、Angularはこのプロジェクトで初めて触りました。にも関わらずこの選択をしたのは、大きく分けて3つの理由があります。

  1. 弊社の別プロジェクトでAngularを使っているものが多かった
    弊社ではいくつか別のプロジェクトがありますが、そちらではAngularを使っている場合が多く、社内では割とAngularが優勢だったりします。社内でのナレッジ蓄積状況を鑑み、またこの開発で得たものを社内に還元するためにも、Angularが好ましい選択と言えました。

  2. セキュリティ面でのメリット
    上記の社内でAngularが優勢な理由にも関わってきますが、Angularを選択することは設計思想的な面でセキュリティ上のメリットがあると考えています。それはバージョン更新のやりやすさです。
    これは私の個人的なイメージの部分も大きいですが、Reactはそれ自体の機能は最小限にしておき、必要に応じて外部のライブラリを追加していくという設計思想だと思っています。一方のAngularは"全部入り"で、(使わない機能も含めて)あらゆる機能は最初からAngularに含まれており、基本的にはAngularだけ導入すれば事足りるという設計思想だと思っています。
    様々なライブラリを使用する上でセキュリティが万全な状態を保つには、使用するライブラリのバージョンを(基本的には)より新しい状態に保っておくのが大切であるという事は皆さんご納得頂けるかと思います。これを考えた時、Reactでは「ある特定のライブラリがReactの最新バージョンに対応していないので、バージョン更新ができない」という事態が比較的発生しやすい気がしています。一方のAngularは全部入りなのであまり外部のライブラリに依存することが無く、依存関係でバージョン更新が阻まれる、という事は比較的少ないのではないかと思っています。事実、追加で導入したライブラリは上記以外だとかなり少ないです。もちろん完全ではありませんが、これもAngularを選んだ理由の一つです。

  3. せっかくの新規プロジェクトなんだから使ったことない技術を使ってみたい
    せっかくだし。

「そもそもReactはフレームワークじゃなくてライブラリだろ」「Angularと比較するならNext.jsだろ」等の意見がある方もいらっしゃるかもしれませんが、React以外なら他のVue.js等も含めてどれを選んでも私にとって初体験であることには変わりありませんでした。ならば上記の理由からAngularにしよう、という事で主軸となるフレームワークは決まりました。

UIライブラリ:PrimeNG

primeng.org

全てのコンポーネントを自前で実装するという手段もありますが、開発期間も人数も限られている中では少々厳しいです。ついでに、私はCSSが物凄く苦手(今でも苦手)なので、その意味でもなるべく見た目の調整を頑張る時間は削りたいです。開発期間中は何の利益も生まないプロジェクトですし、ある程度のスピード感で動くものを見せるためにも、UIライブラリは欲しいところでした。
Angular用のUIライブラリはいくつかありますが、大きなものだとAngular MaterialPrimeNGの2択になるかと思います。ライセンスや費用感、メンテナンス頻度や見た目の好みなどの諸々を社内で検討した結果、PrimeNGを利用することに決まりました。

CSSライブラリ:PrimeFlex

primeflex.org

これは当初導入の予定はありませんでしたが、前述のPrimeNGが一部このPrimeFlexでスタイリングすることを前提に作られているので、半自動的に導入した形になります。

Linter/Formatter:Biome(Rome)

biomejs.dev

LinterとFormatterには、両方を兼ねるRome(現在はBiome)を採用しました。途中でRomeプロジェクトが中止になり、Biomeに引き継がれたためそのまま移行した形になります。
一般的なTypeScriptプロジェクトでは、ESLintとPrettierを導入するのが主流だと思います。この構成にせずRomeを選んだ理由としては、やはり設定がLinterとFormatterの一括で、それもかなりシンプルに済む事が大きいです。あとやっぱり新しいものが使ってみたかったです。

開発を進めて見えたメリット/デメリット

上記の技術選定の答え合わせとして、ここまで約9ヶ月ほど開発を進めてきた結果見えてきた、それぞれのメリット/デメリットを挙げていきます。なお、特定のライブラリを貶める意図は全くございません。あくまで個人の感想になりますのでご了承ください。

Angular

メリット

Web標準的でオブジェクト指向的な分かりやすさ

Angularはクラスベースのコンポーネントを採用しており、コンポーネントの状態や挙動を定義するクラスが含まれるTSファイル、コンポーネントの見た目を定義するHTMLファイルとCSSファイルで構成されます。一般的なWeb技術の範囲から逸脱しすぎないので理解しやすく、TSXファイルなどフレームワーク独特のお作法に振り回されることが少ないように感じています。また、Reactが関数ベースのコンポーネントである性質上、コーディングの際に気をつけないと中間の変数が散らかってどの値を実際に使っているか分かりづらいといったことがよく発生していたのですが、Angularの場合基本的に表に出るものはクラスのプロパティとメソッドだけなので、表に見える必要のないものは隠蔽でき、コードがスッキリしやすいと感じています。Angularは自分を律することが出来ずコードが散らかりやすい人間にも書きやすいです。
もちろん、Reactが様々な理由からクラスベースコンポーネントから関数ベースコンポーネントに移行したことは知っていますし、両者それぞれ一長一短であることは承知しています。ですが、関数型プログラミングに慣れきっているというわけではない場合、Angularの方が既存のパラダイムの感覚をそのまま使えて直感的にコーディングしやすいなという感想です。特にReactを使っていた時によくあったuseEffectを使う副作用周りでの悩みはほぼ無くなりました。

状態管理のしやすさ

Reactを使っていた時、useStateやuseContextを使った状態管理は安全ではあるかもしれませんがやはりちょっと煩雑だなと感じていました。しかしその辺を楽にしようとして外部の状態管理ライブラリを導入すると、それはそれで先述の依存関係問題が発生します。
一方、Angularは非常に状態管理がやりやすいと感じています。コンポーネント内での状態管理は単純にクラスのプロパティとして定義すればいいだけですし、グローバルな状態はServiceが受け持ってくれます。雑に書いても期待通りに動くので、やはり直感的にコーディングが出来ています。

デメリット

情報の少なさ

やはりAngularを選択する上での最大のデメリットはこれです。人気がありません。フロントエンドの話題で出てくるのは8割がReactです。何か困った時に調べてもとにかく情報が少なく、日本語はおろか英語でも中々情報が出てこないことは多々あります。結果として、自力で何とかするしかない事が多いのも事実です。その分力はつくと思いますが……

ヘッドレスUIライブラリでスタンダードとなるものがまだ無い

特に最近感じていることですが、開発後期になってくるとUIライブラリをそのまま使うだけでは要件を満たせず、無理矢理なカスタムをしたり一から実装したりすることも段々と増えてきます。そうなった時に欲しくなるのが見た目の部分だけ完全に自分で実装できるヘッドレスUIライブラリですが、AngularにはReactやVueでいうHeadless UIのようなデファクトスタンダードとなるヘッドレスUIライブラリがありません。じゃあまだデファクトスタンダードにはなっていないものならあるのかというと、それすらも私が探した範囲だとちょっと見つかりませんでした。あまり外部に依存しなくていい代わりに、外部に依存したい場合の選択肢も少ないのがAngularの辛いところです。

人が集まらない

私は人事方面には深く関わっていないので直接体感したわけではないですが、人気が無いので開発者も集まりづらそうです。実際、同じ開発チームでバックエンドを専門にやっているメンバーはAngularが嫌いだそうです。

PrimeNG

メリット

豊富なコンポーネントの種類

約80以上ものコンポーネントがあり、少なくとも開発初期で「このコンポーネントが無いから自分で作らないと……」となることはほぼ無いと思います。機能も結構豊富です。以下にデメリットをつらつらと書き連ねてしまいましたが、良いUIライブラリであることは確かです。

デメリット

時折垣間見える不安定さ

しばらく使っていて分かったことですが、PrimeNGはマイナーバージョンの更新で結構な破壊的変更をやってきます。例えばこちらのissueでは16.3.1から16.4.0にアップデートすると既存のスタイルが壊れるという問題を取り上げており、メジャーアップデートとして扱うべきだと意見が挙がっていますが、この記事を書いている段階では未だにCloseしていません。他にも同じバージョン16の間にButton要素のスタイルの指定方法が変わったりとそれなりに大きい変更をやっており、さらに致命的なのは公式ドキュメントでは各メジャーバージョンの最新版のドキュメントしか参照できないという事です。つまり、マイナーアップデートで起こった破壊的変更について、以前の情報は一切参照できません。
また、その公式ドキュメントも時に不安定で、11月末ごろに突然バージョン16のドキュメントだけが見られなくなったりしました。最新版はバージョン17ですが、まだRC版なので安定版のバージョン16のドキュメントが参照できないのは結構致命的です。この記事を書いている2023年12月4日現在はバージョン16のドキュメントは見られますが、検索ボックスが無くなっていたりアイコンの一覧が表示されなくなっていたりと、完全な復旧には至っていません。以前PrimeNGに対して軽微なバグ修正のプルリクエストを送りましたが、最初の反応があるまでに2ヶ月かかったりと、コミュニティ主導ではなく企業が製品として開発している割にはちょっとスピード感が遅めだなぁというのが正直な感想です。

PrimeFlex

メリット

PrimeNGとの親和性◎

PrimeNGを導入したことで連鎖的に導入したので当然といえば当然ですが、PrimeNGとの親和性は良いです。それ以外に関しては一般的なCSSライブラリと比較して、特に大きな差はないのではないかと思います。

デメリット

足りないCSSプロパティも結構ある

例えばline-clampが無いなど、足りないCSSプロパティもそこそこあります。最近はPrimeFlexに頼らず、直接CSSを書くことも多いです。とはいえ、これもどのCSSライブラリを使っても起こり得る問題だとは思います。

Biome(Rome)

メリット

とにかく設定が楽

JSONファイル1個でLinter、Formatterの設定が一望出来て、かつ設定方法も簡潔なのはとても良いです。手間をかけるべきは開発環境の整備よりも開発そのものだと思うので、開発環境はパパっと整うに越したことはありません。売りである実行速度も直接比較したわけではないので確かな事は言えませんが、意識したことがない程度には速いです。導入当時、既に既存ツールとの互換性もかなり問題ない部類ではありましたが、先日Prettierとの互換性が96%以上になったという発表がありました。今後の発展も期待できそうです。

biomejs.dev

デメリット

VSCodeの言語サーバがよく落ちる

これは私の環境だけかもしれませんが、VSCodeのLSPで使っているBiomeの言語サーバがよく落ちます。コードの規模が大きくなるにつれて頻度が増えてきた印象です。すぐ再起動できるので致命的ではありませんが、ちょっとしたストレスではあります。

ググラビリティに欠ける

前身であるRomeも現行プロジェクトであるBiomeも、シンプルで一般的な単語なので非常に検索性に欠けます。この辺は単体で検索しても期待通りの記事が出るPrettierやESLintに圧倒的に軍配が上がります。

まとめ

EASMのフロントエンドにおける技術選定の観点と、正式リリースが近づいた今その結果を振り返ってみました。総評としては、AngularとBiomeを選択したことは多分正解。PrimeNGは良いライブラリではあるものの、開発が進むにつれてこちらの要件との乖離も発生してきた為、ちょっと悩んでいるという感じです。
技術選定は常に悩みどころで、ある時はそれが最善の選択でも時間が経つにつれて要件に合わなくなったりします。開発リソースやタスクなど諸々を加味しつつ、より良いサービスをより早く提供できることを目指して、日頃から様々な技術へのアンテナは伸ばしていきたいです。

あと、願わくばAngularがもっと流行ってほしいです。