初めまして、株式会社アドグローブ ソリューション第三事業部の中野です。
新しいプロジェクトをスタートする際、どの技術やフレームワークを採用するかは大きな決断の一つです。
「どの技術やフレームワークを採用すれば良いのか・・・」
私自身、いつも凄く悩んでいるポイントです。
私が最近関わった案件では、Reactを中心としたフロントエンドの技術選定に必要な情報の収集や実際の環境構築、アーキテクチャ設計を担当しました。
今回は、技術トレンドを追いつつも、実際のプロジェクトニーズに合わせてどのように選定をしたのか、またアーキテクチャはどのように設計されたのかを詳しく共有したいと思います。
特に新しいプロジェクトをこれから始める方や、技術選定の経験を深めたい若手エンジニア、フロントエンドのアーキテクチャに興味がある方に、この記事が参考になれば嬉しいです。
はじめに
今回、私が関わった案件について簡単に紹介します。
この案件は、WebブラウザとWebViewを使用したアプリの開発でした。フロントエンドとバックエンドは完全に独立しており、APIを介してデータのやり取りをしています。私がプロジェクトに参加した時点で、Reactを使用することはすでに決定されていました。しかし、その他の技術やツールについては、私を含む参加したエンジニアたちで決めていく必要がありました。
まず、ポイントになった技術選定やアーキテクチャ設計について紹介して、その後にどうだったかという点に触れて行きたいと思います。
技術選定
主に使った技術について簡単に紹介していきます。
要件にマッチしているか、安定して使えるか、開発スピード、コスト面を考慮しています。
Next.js
プロジェクトの初期段階で、Reactをそのまま使用するか、あるいはReactベースのフレームワーク(以下、FW)を採用するかの選択が必要でした。特に、SEO対策を強化したいという要件や、ユーザーアクションに応じて動的にコンテンツを変化させる必要があったため、レンダリングはSSRを採用しました。
SSRを実現するための最適なFWを検討した結果、Next.jsを選択しました。Next.jsの魅力は、単にSSRを実現できるだけでなく、情報が豊富であること、そしてゼロコンフィグの特性(完全に設定不要ではないものの、Reactのみを使用するよりは設定が簡単)が挙げられます。私たちのプロジェクトでは開発スピードを重視していたので、このような特性は有益でした。
Tailwind CSS
Reactの開発においては、さまざまなCSSの記述方法やフレームワークの選択肢が存在します。今回のプロジェクトでは、独自のデザインを構築する必要があり、ブラウザ間のデザインの差異を無くすためのCSSリセットが求められました。
Tailwind CSSは、CSSリセットが組み込まれており、既存のクラスをそのまま使用できるフレームワークです。この特性により、各コンポーネントごとに別々のCSSファイルを作成する必要がなく、クラスを直接記述してスタイルを適用することができます。これはReactのコンポーネントベースの開発と相性が良いです。
Tailwind CSSの学習には初めのうちは時間がかかるかもしれませんが、一度慣れると、ファイルやクラス名の管理にかかる時間を大幅に削減でき、開発をスピーディーに進めることができます。これらの利点と、プロジェクトの要件にマッチしていたため、Tailwind CSSを採用することとなりました。
MSW
MSW(Mock Service Worker)は、ブラウザのリクエストをインターセプトしてAPIをモックできるライブラリです。今回のプロジェクトでは、フロントエンドとバックエンドの開発が並行して進行するため、実際のAPIが完成する前にフロントエンドの開発を進める必要がありました。APIの待ち時間で開発が停滞することや、APIとの結合時にバグが発生するリスクを軽減するため、MSWを採用しました。
OpenAPI(Swagger)とTypeScript
フロントエンドとバックエンド間でAPIのインターフェースをどのように管理するかは、常に課題となります。今回のプロジェクトでは、コードベースでAPIのインターフェースを管理するためにOpenAPIを採用しました。Gitでの管理が可能なため、変更の差分が明確になり、さらにドキュメント生成やコードの自動生成などの利点も受けられます。しかし、どの程度の自動生成を行うかは慎重に検討する必要がありました。ライブラリに依存することで柔軟性が失われるリスクを考慮し、今回はTypeScriptの型のみを自動生成することに決定しました。「openapi-typescript」というライブラリを使用しました。
採用しなかった技術
検討して採用しなかった技術もありました。その一部を紹介します。
Storybook
デザインやコンポーネントの変更に伴うストーリーファイルの修正が必要となるため、メンテナンスコストが増加する可能性が考えられました。さらに、Storybookの学習や導入に関するコストも考慮し、採用を見送ることとなりました。
E2EテストFW
現在、Playwright、Cypress、Puppeteerなど、多くのE2Eテストフレームワークが提供されています。E2Eテストの自動化はリグレッションテストには有効ですが、正確なテスト定義の作成や、初期段階での頻繁な変更への対応が必要となるため、コストが高くなる可能性がありました。また、これらのフレームワークの学習コストも考慮し、採用を見送ることとなりました。代わりに、JestやTestingLibrary、バックエンドのテストで品質を確保する方針を採用しました。
アーキテクチャ設計
主にNext.jsに絡んだ部分になります。
一人で作っていくわけではないので、メンバーが理解できて作りやすく、開発効率がなるべく良くなるように考えてみました。
AppRouterとPageRouter
Next.jsのAppRouterが安定版になりましたが、まだ情報が少なく、時期早々なのかなという感じがしています。
安定しているPageRouterを採用することにしました。
コンポーネント・ディレクトリ構成
以前、アトミックデザインを採用していて、どう分けるかやディレクトリ構造で悩んだ経験がありました。
今回はそれもあってアトミックデザインを採用せずになるべく単純に分けていこうと思い、構成を考えてみました。
「bulletproof-react」を参考にしています。具体的にはcomponentsディレクトリを作り、ボタンなどの共通で使えるものはそこに入れて、機能に依存したコンポーネントはfeaturesディレクトリに作成していくようにしました。
組んでいて特に良かった点としては、featuresにroutesを作ったことでpagesのファイルが肥大化せずに済み、見通しが良くなったことです。
下記は構成の一部
📦 root
┣ 📂 components 共通コンポーネント
┃ ┣ 📂 Elements 要素コンポーネント
┃ ┃ ┣ 📂 Button
┃ ┃ ┣ 📂 Card
┃ ┃ ┗ 📂 ...
┃ ┣ 📂 Layout
┃ ┗ 📂 ...
┣ 📂 features 機能別コンポーネント
┃ ┣ 📂 featureA
┃ ┃ ┣ 📂 api API呼び出しに関する処理
┃ ┃ ┣ 📂 components routesから参照するコンポーネント
┃ ┃ ┣ 📂 routes 実際の画面を描画するtsx
┃ ┃ ┗ 📜 ...
┃ ┣ 📂 featureB
┃ ┗ 📂 ...
┣ 📂 pages ページ
┃ ┣ 📂 ...
┃ ...
...
結果と反省
実際に開発を進めてみてどうだったかという話を最後にしたいと思います。
Next.jsは使っていくと色々と気付くことがありました。getServerSidePropsはpagesでしか呼べなかったり、どこからがサーバー側で動いていて、どこからがクライアントで動く部分なのか一見して分かりにくいといった点です。AppRouterが出てきたのはそうした課題があったからなんだろうなと思いました。
Tailwind CSSは最初にこんな感じで書くというサンプルをメンバーに共有して進めたのもあってか、思ったより時間が掛からずにメンバーがキャッチアップしてくれて良かったです。CSSの記述量が減ったので、コードの見通しが良くなって単純な作業量が減っていると思います。独自のデザインを組む場面でも解決方法が用意されているので、その点も特に困らなかったです。今後も採用できる場面があれば採用していきたいなと思いました。
API周りではOpenAPIと型の自動生成、MSWとの相性が良かったです。 型があるので組んでいくと間違っていた場合にエラーになります。これによってAPI定義の間違いに気付きやすく、YAMLなので修正も簡単でした。MSWでモックしていく際に自動生成された型が使えるので、変更があっても反映がしやすかったです。バックエンドとの結合前に簡単に試していける点も良いポイントでした。
おわりに
フロントの技術は移り変わりが早いですが、かといって最新のFWを使えば良いというわけではないんだと思っています。新しいFWを安易に採用すると、扱えるエンジニアが少なかったり、ドキュメントや情報がなく、課題に直面した時に苦労します。
要件を確認して、最適だと思う物をロジカルに選択していく必要があるんじゃないかと思いました。
今回の記事が何か参考になれば幸いです。
最後まで読んでいただきありがとうございました。
参考リンク
openapi-typescript:
https://github.com/drwpow/openapi-typescript
bulletproof-react:
https://github.com/alan2207/bulletproof-react
現在アドグローブでは、さまざまなポジションで一緒に働く仲間を募集しています。
詳細については下記からご確認ください。みなさまからのご応募お待ちしております。
hrmos.co