自作WebアプリをReactからAngularに移行した話
はじめに
以前こちらの記事で紹介した、漢字テストメーカーというWebアプリがあります。
当初覚えたてのCreate React Appで作っていましたが、当のCRAが非推奨になったこともあって、そろそろバージョンアップしたいなと思っていました。単純にNext.js等で作り直してもよかったのですが、本業でAngularを使っておりReactよりAngularの方に良さを感じ始めていたため、ここらでAngularに全移行しようと思いました。
また、漢字テストを作成できるアプリはある?スマホで無料で作る方法 | studywith|親子の学びブログで拙作の漢字テストメーカーが紹介されているのを目にしました。使いにくいところ・不満点という形で改善要望が挙げられていたので、それもついでに対応することにしました。
Angularを選んだ理由
上記の通り、Angularを選んだ理由は本業で主に使用しているからですが、Angular自体が気に入っているというのもあります。日本でのSPAフレームワークの流行りは圧倒的にReact(Next.js)、次点でVue。Angularはかなり下の方だと思います。にも関わらずAngularが好きなのは、以下のような理由によるものです。
全部入りのためアップデートしやすい
React系列は本体の機能は最低限に抑えておき、必要に応じて状態管理などの外部ライブラリを導入してカスタムしていく使い方が一般的なのではないかと思います(Next.jsやVue系などだと違うんでしょうか?使ったこと無いのでよく分からずすみません……)。一方のAngularは基本的に「全部入り」のため、必要な機能は全てAngular自体に組み込まれており、外部のライブラリに頼る必要はほとんどありません。そのため「依存するライブラリのバージョン更新が追いついていないため、全体のバージョンアップができない……」というような状況に遭遇しづらいと感じています。
漢字テストメーカーは完全にスタンドアロンで動くアプリなので別にバージョンが古くても大した脆弱性の影響は受けないためあまり関係なくはあるのですが、やはり最新バージョンに保ちやすいというのは精神衛生的に良いです。
標準的なWebの知識で対応できる
Angularのコンポーネントは主にHTMLファイル・CSSファイル・JavaScript(TypeScript)ファイルの3つから構成されます。それぞれが分離しているため、ReactのJSX・TSX等よりも伝統的で標準的なWebの知識が適用しやすいです。また、比較的フレームワーク固有のお作法を覚える必要が少ない気がしており、Reactの時は常に悩まされていたuseStateでの状態管理やuseEffectを使った副作用の取り扱いなどで悩むことがほとんどなくなりました。「Angularは学習コストが高い」というのはよく言われますが、ReactからAngularに頭を切り替える際のコストが高いだけで、Angular自体の学習コストは割と低めなんじゃないかと思います。
今回の改善ポイント
上記のサイトで要望として挙げられていたのは以下の点でした。
- ダウンロード後に戻って修正できない
- 一文中に2箇所の問題を作ることが不可能
- スマホ版で枠がずれる
- 問題種別の選択で「書き」をデフォルトにしてほしい
- 問題データの保存ができない
動作の不具合や画面レイアウトの改善等は単純にやるだけですが、今回の大きなポイントとして「ダウンロード後に戻って修正できない」に対応するために行った、問題画像作成ロジックのワーカースレッド化があります。
以前の実装では「問題作成」ボタンを押下したあとにコンポーネント内で問題の画像を作成する関数が走り問題画像が出力されるという仕組みでしたが、そのロジックをワーカースレッドとして切り出すことで、フォームへの入力と同時に並列で画像を生成し、リアルタイムに表示することができるようになりました。また「問題データの保存ができない」に対応するため、jsonでのエクスポート/インポート機能も追加しています。
一方「一文中に2箇所の問題を作ることが不可能」については、今回は対応を見送ることに決めました。例えば「漢字と漢字」という問題文があり「漢字」が問題になる箇所として指定された場合、問題になる箇所が最初の「漢字」なのか2つ目の「漢字」なのかが判別できないためです。重複する文字列があれば全て問題になる箇所として指定することは可能だと思いますが、今回は他の部分の実装を優先しました。
移行手順
移行手順は単純で、
- プロジェクトに新しくAngularを導入する
- Reactのコンポーネントを見ながら、それを手作業でAngularのコンポーネントに置き換えていく
- 全部終わったらReactをアンインストール
で完了しました。単純ではありますが大変でした。とはいえ、この機会にアプリの構成を整理することもできたので、やってよかったと思います。
Angular以外にはTailwind CSSとPrimeIconsを導入しています。当初はPrimeNGというUIライブラリを使用しようと思っていたのですが、ver16.4から全体のmarginを0にするというよくあるリセットCSSに影響を受けてスタイルが崩れるという問題が発生しており、最新のver17系でも改善されていません。このままではちょっと使えないな……と思ったため導入を取りやめ、TailWind CSSでスタイリングすることにしました。ただ、各コンポーネントのデザインやプロパティ等は参考にさせてもらってます。また、関連するPrimeIconsというアイコンのライブラリはデザインが気に入ったため継続して使うことにしました。
成果物
冒頭にも貼りましたがこちらです。
地味にPWA対応などもしております。ほぼng add @angular/pwa
を実行するだけで終わってビビりました。
Discussion