🏫

今更書く新歓Webサイト開発の話

2023/12/08に公開

こんにちは、京都工芸繊維大学で卒業までの時間が短くて焦るマンゴーさんです。今回は、4月に作成していたWebサイトについての話を書いていこうと思います。

関連記事: 大学新歓サイトのフロントエンドを開発していました もご覧ください!

新歓Webサイトの内容について

まずは実際の成果物を見てみましょう。

今回作成したWebサイトでは、「相性診断」と題して新入生への部活動のレコメンドを行いました。そして、レコメンドされた団体を見学していくことでプレゼントが貰えるというスタンプラリー企画も同時に実施しました。この企画は、企画部irodoriさんと大学の新歓委員会、そしてあくあたん工房が合同で行いました。コロナ対策の都合などもあり、あまり大きな反響はなかったものの、新歓のときの部活動情報サイトとしてうまく利用してもらえたかなと思います。

私は、このサイトの開発において開発の主導とバックエンド開発の2つを行っていました。そこで、この記事では、サイトを作る上で技術面やチーム開発でどのようなことをしていたのかを共有します。学祭や部活動のサイトなどを作る人の役に立つ内容を共有できればと思います。

開発の方針

今回は企画立案が12月で、開発開始が1月、公開が4月と余裕のあるスケジュールでした。また、メンバーについても私、ゆゆくんなどがすでに参加を表明してくれていたため、(ハッカソン的ではない)しっかりと手順を踏んだチーム開発を行おうと考えていました。過去の開発の経験がワンマンであったり、コミュニケーション不足であったり、その場しのぎなものが多かったというのも理由の一つです。また、教え合う機会を設けることも方針に組み入れました。どのメンバーも最新のフロントエンド開発の経験はあまりなかったため、知識を学びながら開発しないとどこかで行き詰まると感じたためです。メンバーの経験のためにもこれは良い選択だったと思います。

これらをもとに決めた大枠の方針を決めました。
大枠の方針

  • チーム開発を意識する
  • 教え合う機会を設ける

これをもとに、

  1. 技術選定をしっかりと議論する
  2. デザインツールによりデザインを作成する
  3. レビューや通話などで教え合いながら開発する

の開発の流れと、

  1. 開発支援ツールやCI/CDを取り入れる
  2. GitHubのIssue / Pull Requestを使ってレビューや各種Gitフローを行う

という方針が決まったのでした。私としては、デザインツールの利用や技術選定のフローは初めてのものでした。

技術選定

まず、利用する技術の選定を行いました。技術選定では、ある程度脳内で考えていた機能を実現できることと、Webサイトの特性をベースに選定を行いました。

機能面

この部分は、企画立案の段階で企画部irodoriさんと会議をして決めたものです。ここで決めた内容はUIなど、利用者から見える部分に関わってきます。

  • 一人ずつのレコメンドを保存できる
    • 景品交換のためにサーバーサイドで保管できる
  • 訪問した団体を記録できる
  • レコメンドをSNSで共有できる
    • (OGP画像の動的生成をやりたいと考えていました)
  • リアルでの景品交換のためのUIがある
  • 団体の情報を新歓委員会側で更新できる
    • (データ入力はしんどいですからね…)

機能の数は少ないですが、データの永続化やサーバとの同期が必要だったりと真面目に実現すると少し複雑になりそうな内容になっていることがわかります。

特性面

次に、機能を実現する上でどの程度のリソースが必要になるかなどを考えるため、Webサイトの特性についても考えました。こうした特性から導かれる、技術面寄りの内容は「非機能要件」とも呼ばれ、開発をする上で見落としてはいけない要素になります。
今回のWebサイトは大学全体を対象としているため、ある程度大きく見積もりをしておきました。

  • 利用者は新入生の全員を想定する
    • 小さい大学といえ、500人程度は入学する…
    • 同時接続100くらいは超えるかも?
  • アクセスは全員が同時に行っても大丈夫にする
    • もともとはイベントとして一斉にアクセスしてもらう前提でした
  • 費用はできるだけ掛けたくない
    • クラウド破産NG
  • Writeはあまり起こらない
    • レコメンド初回作成・団体の訪問・プレゼント交換の3場面のみ

このように、Webサイトの特性を考えた上で技術を選んでいきました。さらに、これ以外にもDeveloper Experienceを強化できることも重要視しています。

この段階で選んだ技術は以下の通りです。
ただ、Webに詳しい人が少なかったため、発案者(私)の意見が割と多く取り入れられています。ですが、バックエンドについては、有識者の方と議論をした上で決めることができています。

名前 内容
Figma デザイン案の共同編集
Next.js フロントエンドフレームワーク
Storybook UIコンポーネントの動作確認
OpenAPI バックエンドのAPIスキーマ定義
Cloudflare Pagesでホスティング、Workerでバックエンドを用意
Newt 団体情報を管理する

詳しく見ていきます。

Figma

Figmaは開発するWebサイトのデザインを作成するために利用しています。これについては「チーム開発をするならまずデザインの認識を共有すべき」という思想によるものと、Web開発者以外のアセット作者や責任者にも早い段階でデザインを見てレビューしてもらいたいという必要性の2つから採用しています。
実際のFigma↓

Figmaでのデザイン制作はメンバーすべてが初の経験だったことと、テスト期間との重なりもあって1か月弱かかっています。ですが、色々なカラーバリエーションやコンポーネントのデザインを試し、デザインに集中することができていました。また、共同編集ができるので、Discordで集まってデザインについて議論することもできました。最終のUIは見やすいものになったと自負しています。

Next.js

これについては、デファクトスタンダード的な採用理由で、あまり細かくは書きません。
今回はApp Routerについてあまり情報がなかったこともあり、Pages Routerを採用しています。Webサイトとしてはサーバサイドで行う処理が多いため、来年作るのであれば、App Routerを活用してもいいのではと思っています。(フロントエンド業界の進化は早いものですね…)
なお、開発言語はTypeScriptを用いています。

フロントエンドについては、開発メンバーのゆゆくんの大学新歓サイトのフロントエンドを開発していましたをご覧ください。

Storybook

Figmaの段階でコンポーネントの粒度はある程度決めてありました。あとはそのコンポーネントを実装していくのですが、今回はUIエレメントについてカタログとしてのStorybookを作成していました。Storybookにより、(Figma上で)ページ全体が完成しなくても一部のUIを作成して評価し、挙動を確かめることができました。また、途中からChromaticと組み合わせてのビジュアルリグレッションテストも行っていました。
他の人が作成したUIコンポーネントを使う際に、propsによりどういう挙動をするかを確かめながら使う、というような場面や、テストデータを流し込む場面で重宝しました。

OpenAPI

今回の開発では、データの永続化などを担うバックエンドと、UIを担うフロントエンドに分かれ同時並行で進んでいきます。そのため、事前に両者でインターフェースについて合意が行われていないといけません。そこで、OpenAPIを用いて事前にインターフェースを定義しておきました。
APIを定義しておくことで、型の整備や、フロントエンド側でのMSWによるモックを行うことができました。また、APIを考える段階で機能について考えることもできました。

Cloudflare

Webサイトのホスティングやバックエンドの機能はすべてCloudflareで行っています。

  • Cloudflare Pages: ホスティング
  • Cloudflare Workers: バックエンド機能
  • Cloudflare D1: データ永続化
  • Cloudflare R2: 動画ファイルなどのリソース
  • Cloudflare KV: キャッシュ

Pagesにはnext-on-pagesを用いてデプロイしています。また、WorkersではHonoを用いてAPIを提供しています。

Cloudflareを選んだ理由としては、無料枠の大きさ・Edge実行での速度・CI/CDへの対応があります。
PagesはOutboundの帯域制限がないため、大量のアクセスがあったとしても課金が生じません。Workersも20万回/日の実行回数が無料なので、アクセスが集中しない限りは十分利用でき、サイトの運用が終わっても残すという選択ができます。また、実環境と同じものを、お金のことを考えずにすぐ用意できるという点でも無料枠の大きさは魅力的です。
他のFaaSと違い、すべてEdgeで実行されるため、APIが遅くなることもほとんどありません。
開発者視点だと、Pagesは、GitHubのPRやブランチごとにプレビューを作成してくれるため、実環境と同じ環境ですぐデバッグすることができます。

PRでデプロイされている様子

D1やKVなど、一通りの機能を実現できるサービスの提供もありました。

Newt

Newtは各団体のデータを管理するために利用しています。サービスとしては通常のHeadless CMSですが、画像などの転送量への課金がないこと、ユーザー数の制限があまりない(当時)ことから採用しました。無料枠の大きさは学生にとって有難いことです。
使ってみた感想としては、UIがNotionを意識していて、データ構造に寄らず扱いやすいことが良かったです。

その他のツール

開発を進めるうえで、linterやformatterなどのツールを導入していました。具体的には、eslintprettierstylelint、そしてhuskyです。eslintはTypeScriptやHTMLなどの好ましくない問題を検出・警告してくれます。prettierは多言語対応のフォーマッタです。stylelintは、CSSの書き方の問題を検出してくれます。これにより、機械的にチェックできるエラーや非推奨事項はすべてレビュー前に修正させることができています。
また、huskyを用いることで、警告やエラーがあるとそもそもGitにCommitできないようにしています。使っていて、少しうるさく思うこともあったので、過剰だったかもしれませんが、完成したらCommitする(完成していないと怒られやすい)という習慣は付いたような気がします。
加えて、バックエンドのみですがJestによるユニットテストも行っています。

開発の流れ

まずは、全体を通しての開発の流れを見てみます。

FigmaでのUI作成

UIは、全体的なものを私とゆゆくんで設計していました。最初は、Figmaのチュートリアル動画を見て操作やコンポーネントの概念、助かる拡張機能などを知るところから始めました。その後は、各自で(授業期間なので)空いた時間に作業をしたり、Discordの作業通話で行いました。
UIの作成には大体1か月程度かかっていたように思います。途中から、フロントエンドの開発にもシフトして、コンポーネントを少しずつ作成してもらっていました。
Figmaでは、サイトのレイアウトがほぼ決まっていたので、後々のフロントエンド開発にも役立っていたと思います。

IssueとPull Requestベースの開発

開発においては、Issueを立てて作る機能と担当者を宣言し、Pull Requestで実際にマージする流れで行っていました。またIssueやSlackで困りごとを書いておくことも行っています。

Issueの例

作業通話

記事の最初のほうで、「Web開発に慣れていないメンバーもいる」と書いていたと思います。そうしたメンバーも戦力として開発できるよう、また、悩み事をすぐ解決できるようにDiscordで作業通話を行っていました。画面を共有することができるので、バグった挙動がすぐわかるという利点もあります。1つのことを同時に行うペアプロとしての役割もあり、教える側も理解を深めることができたと思います。
また、開発に直接関係しないメンバーも通話に参加していることがあるなど、Web周りに興味を持ってもらうという役目もあったと思います。

作業通話時の様子

バックエンドの開発

バックエンドの開発は、今回私が主に担当していた部分です。OpenAPIのSchemaに基づきながら、Honoを使ってAPIを作成していました。今であれば@hono/zod-openapiなどを使うところですが、当時は無かった(?)ため、Aspidaで定義だけを作成して使っていました。
データベースについては、D1を利用していますが、ORMは特に利用していません。
コードについては、データベースアクセスを担うrepositories、データを保持・処理するmodel、API要求を処理するcontrollersと簡潔に分けて記述していました。このあたりはAPIのレポジトリのREADMEを読んでもらえればと思います。
また、各コンポーネントについて、JestによるテストをGitHub Actionsで行っていました。

感想

チーム開発ができる開発フロー、を意識していましたが、設計の共有でのコミュニケーション不足や、見通しの甘さがどうしてもありました。その結果として若干の納期の遅れが生じるなどもしていました。コミュニケーションの技術もチーム開発では重要になるため、今後も経験を積んでいきたいです。
また、ドキュメントや仕様書の作成を含む、仕組みの整備をより時間をかけて行うことで、より円滑に進められたようにも感じます。また機会があれば試してみたいものです。

謝辞

サイト開発に関わってくれたすべてのメンバーに感謝します。

(敬称略)

Discussion