Next.js + Cloud Runで管理画面をリファクタリング・技術選定編

2022/12/05に公開

はじめに

どうも、いとーです。
社内ではito-run(いとらん)という名前が浸透している、フロントエンドを中心としたフルスタックエンジニアです。Aidemy Businessの開発チームに所属しています。
Aidemy Businessとは、簡単にいうとDX人材を社内で育成できるようなコンテンツを提供してる学習アプリです。
本記事ではAidemy Businessというサービスのフロントエンドを一部ファクタリングしたので、そのときの技術選定を中心に共有できたらと思います。

概要

創業時から果敢にさまざまな価値提供をしていたサービスであり、ありがたいことに安定してユーザが増え機能も増えているのですが、テストをかきずらいコードなどからフロントエンドのコードが開発・保守がしずらいんじゃないかという懸念がありました。そこをきっかけにフロントエンドの一部ファクタリングをしリプレイスも行いました。
フロントエンドのコードとしては受講者画面と管理画面があるのですが、受講者の演習画面やテスト回答画面の機能、管理者のもろもろの機能など膨大なため今回は分離させやすい管理画面からファクタリングされています。そのため、レポジトリやインフラも管理画面のもののみ新たに作成されています。

管理画面・システム構成

  • フレームワーク
    • Next.js
  • 言語
    • TypeScript
  • CSS ライブラリ(フレームワーク)
    • Chakra UI
  • インフラ
    • Cloud Run(GCP)
  • デザインシステム
    • Atomic Design

ライブラリ・フレームワーク選定

Next.jsを選定しましたが理由は以下でした。

  • ゼロコンフィグ
    • Next.jsがパフォーマンスを良い形に設定してくれているので特に詳しい設定がいらない。
    • そのため、設定したメンバーに知見がかたよることもありません。
  • いきおいのあるフレームワーク
    • Next.jsのコミュニティはさかんであり、ネット上に知見がたまっていることは安心できました。
  • React.jsライク
    • Reactでフロントエンドが書かれていたのでチームに親和性がありそうでした。

ちなみにRemixも気になったんですが、まだ安定して稼働している実績や知識が界隈でたまっていないのであつかにくそうという判断になりました。

参考リンク

インフラ選定

インフラはGCPで設定しました。

  • Cloud Run
    • フロントエンドやバックエンドはGCPで稼働しており、扱いやすや単一障害点をへらすことから今回もGCPを利用
    • Kubernetesほどフルマネージドなものは必要なく Next.jsのSSRを利用できるサーバーがよい
  • Cloud Armor, Cloud DNS, Cloud Load Balancing
    • ドメインやサーバ証明者、IP制限など適宜設定されている

Cloudflare Pagesも比較にありました。また、 DevOpsに関してはCircle CI上で特定のブランチにマージされるとImageがDeployされるように設定されています。

参考リンク

よかった点・悩んだ点

Chakra UI

良かった点

  • あつかいやすいコンポーネントをさくさくつくれる
    Chkara UIを少し覚える手間がありますが、基本Chakra UIが提供してくれるコンポーネントを直感的に配置していけば良いので、さくさくコンポーネントができあがります。
    また、Chakura UIが用意したコンポーネントを利用すれば、CSSの適応範囲がわかりずらいなどのコードの複雑さはおのずとなくなるので採用してよかったなと思っています。CSSの作法やCSSの有効範囲の指針をチームで詳しく設定しなくていいのも良さでした。

  • Themeが便利
    Themeとは、利用しているChakra UIライブラリに共通の設定を追加できるもので、うまく利用すればresponsive対応やダークモードの対応などもできます。フォントやz-indexの値などをそろえるのに役に立ちます。

悩んだ点

これはいまでも答えを探しているんですが、Atomic Designにはまっているかはわからない点です。
Atomic Designでは、atoms, molecules, organisms, templatesのようにUIコンポーネントを大きさでくぎっていくものなのですが、そもそもChakra UIが用意したもの(たとえば、Button)をわざわざAtomsとして定義しているような場面があります。
Atomsとして用意しても結局Chakra UIから直接持ってきたほうがよく作成されたAtomsの方は使われないケースがあるので、再度コンポーネント整理はやろうと思っています。

参考リンク

コード指針

悩んだ点

  • Redux or Context API
    • もともとのコードがReduxを採用していたのですが、Reduxはボリュームが多いので設定した人以外が修正するのは少し困難ですしそこまでおおがかりに厳密にglobal stateを持たなくて良いと判断し、Context APIのみを利用するに設定しています。
  • Atomic Design
    • Atomic Designはただのデザインシステムで、チームによってどのコンポーネントがどの分類になるかは相談してきめないといけないらしく以下のような指針を決めました。
    • 可能なら開発が始まる前に設定したほうがチームが混乱が減るので良いと思います。
components/
  atoms/        ... 基本的にタグ1つで形成されるもの
  molecules/    ... 再利用がある複数タグのもの、または特定のorganismsで利用するもの
  organisms/    ... atoms, molecules で形成して用途が明確なものpagesが利用するもの
  templates/       ... pages でレイアウト(テンプレート)利用するもの
pages/        ... URLで表示するページ
- 状態管理とデータのつなぎこみ

|                    | atoms | molecules | organisms | templates | pages |
| :----------------- | :---: | :-------: | :-------: | :-------: | :---: |
| 状態管理           |  ❌   |    ❌     |    ⭕     |    ⭕     |  ⭕   |
| データのつなぎこみ    |  ❌   |    ❌     |    ⭕     |    ⭕     |  ⭕   |

ディレクトリ構造はこんな感じです。

.
└──── src
    ├── components
    │   ├── atoms
    │   │   ├── ListDetail.tsx
    │   │   └── ListItem.tsx
    │   ├── molecules
    │   │   └── List.tsx
    │   ├── organisms
    │   └── templates
    │       └── Layout.tsx
    ├── hooks
    ├── types
    ├── lib 
    ├── locales
    ├── pages
    │   ├── _app.tsx
    │   ├── about.tsx
    │   └── index.tsx
    ├── styles
    │   ├── global.ts
    │   └── variable.ts
    └── utils

参考リンク

まとめ

ざっくりとしたリファクタリングのプロジェクトの概要などを話しました。サービスの提供に関しては問題なく提供できているので他の方も実施するときに参考になると幸いです。
開発者からもとくに大きなつらみはきいていないので今のところこのような形でリリースできたのは良かったと思います。細かな設定などの各記事はネット上にちらばっていますのでがんばって参照しみてください。開発体験として、今はわるくないです。

今後はファイルごとにコンポーネントがしっかり分離したのでテストの追加をしたり、コンポーネントを整理するためにまずStorybookを適応させたりなどを続けて設定していこうと思います。

参考リンク

Aidemy Tech Blog

Discussion