駆け出しエンジニアがReactとTypeScriptとFirebaseで3ヶ月間、アプリ開発に取り組んでみた

# はじめに

私はフロントエンドエンジニアとして2021年の6月から働いている駆け出しエンジニアです。

実務で触れているのはVue.js, Nuxt.jsがメインで、今回のアプリ開発で初めてReactに触りました。この記事はReactの勉強を始めた12月1日から3ヶ月後の2月末までアプリ開発にコミットしてきた足跡になります。

# 背景

11月末に大学時代の友人から「アプリ開発のエンジニアを探しているんだけど、どうかな」とお誘いの言葉をもらいました。

既にプロダクトデモはあるらしくざっくりとしたアプリの概要を説明してもらい、Reactを採用していることや、自分もちょうど案件が落ち着き何か開発をしたいなと思っていたので12月からお手伝いをすることになりました。

いろいろあって開発中盤でクローズすることになってしまったのですが、開発を進めるたびに思い入れが強くなってきたのもあって、せめて日の目を浴びるまでは面倒をみたいと日々、合間を縫って開発を続けました。

アプリに関する情報は参画初期にもらった資料のみでワイヤーフレームもありません。デザインも明確に決まってなく、どんな機能を追加するかも定まっていない中、手探りで「こんな感じかな」「これがあったら便利だな」と肉付けをしていった感じです。

まとめると`初めて触るReactで開発をしたけどアイデアは友人のもの。途中で開発が頓挫したけど最後までやり切りたいから足りない情報は自分の想像で補って作ったアプリ`です。

期間を設けずに進めるとだらけてしまうので締め切りを２月末とし３ヶ月間で実装を終わらせ記事として公開することを目標に開発に取り組みました。

# アプリ概要

<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vS6LUXTGV_kW0e5hYDghlPxWt6ZzwKhgXmKpaPmsNmdNwpRrDsnib8f2G_OTFMiKHjCuTR87XtM3mbO/embed?start=false&loop=false&delayms=3000" frameborder="0" width="500" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

※友人の資料を一部抜粋しています。公開の許可は本人からいただいています。

本来であればアプリケーションの公開をし、多くの方に見ていただきたいと思いましたが下記記事を見て動画のみの公開にしました。

https://qiita.com/nasuB7373/items/10bebd8e9f0b3331f348

## ■アプリ詳細

アプリの名前は`テマナシー`と言います。
その名の通り手間なく家具を選び購入することができる、家具に特化したアプリケーションです。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175826/bc19fcb3-38c2-bf1d-5dc2-11aa5bffe354.gif' width='35%'><img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175826/5233bc70-57b1-505d-5cd1-f92a6a5afe35.gif' width='35%'>

好みの家具を提案できるように診断テストも実装しています。
この機能は`スナックミー`や`Post Coffee`の診断テストをイメージしています。

と言いながらもロジックの部分はタイムアップで実装できず、ランダムで出力される家具をスワイプし切ったらおすすめインテリアとそれに関連する家具一覧を表示する実装になっています。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2175826/e97e24c3-fb3c-8ee7-ab2d-5cf6fbed5ce9.gif' width='70%'>

https://postcoffee.co/

https://snaq.me/



# 実装スケジュール（12月1日〜2月28日）

Reactのキャッチアップに関しては下記記事を参考に進めました。何から手をつけていいか迷っている方がいらっしゃいましたら是非ご覧ください。

https://qiita.com/tsuchiya_kaita/items/6ff4dd6c41ddebf3948c

## ■ 12月

2週間：Reactのキャッチアップ、ワイヤーフレームの作成、DB設計、必要機能の調査など
2週間：骨子の作成（必須コンポーネントの作成や最低限のレイアウト実装）

## ■ 1月

4週間：スワイプ機能や決済機能などのメインの実装

## ■ 2月

2週間：リファクタ・レイアウトの調整など
2週間：記事作成、テストコードの実装など

※フロントdivでは週3回slackのハドルで技術に関するラジオをするのですが、その一枠を使って今回のアプリ開発で実装したコードの解説をし、適宜、先輩社員に指摘してもらってリファクタを行なってしました。実装した背景やどこまでそのコードについて考えたのか復習する機会としてフル活用しました。

# 採用した技術スタック

先に述べたように本格的な機能実装をする前にクローズしてしまい納品する予定がなくなったので「この技術を使ってみたい」という興味を優先しての技術選定になっています。

本来ならCSSモジュールやTailwindを使うべきところを使わなかったり、トークンもFirebaseの発効しているものではなくわざわざJWTを用意したのも自分の興味を優先したことが理由です。

```bash
言語: TypeScript
CSSアーキテクチャ: ITCSS, RSCSS
ライブラリ: React
ホスティング: Firebase Hosting
DB: Firestore
認証: Firebase Authentication
トークン: JsonWebToken
サーバー: Cloud Functions, Express
ストレージ: Cloud Storage
決済: Stripe
E2Eテスト: Cypress
CICD: CircleCI
```

# 実装にあたって残したメモ

今回の実装を通して、躓いたことや気づきをまとめましたので参考になりましたら幸いです。

本当は複数画像投稿の機能や、いいね機能、テストコードで躓いたこと、モーダルやローディングを一から実装してみて思ったこと、画像の読み込み遅延や画像圧縮を通して得たパフォーマンス系の話など色々書きたいのですが…

あまり記事として見かけなさそうなものでピックアップしていきます。

## ■ React編

Firestoreからランダムで5個データを取得し、それをスワイプの増減に応じてプログレスバーも連動するスワイプ機能を実装した時の記事です。react-tinder-cardのライブラリ導入とコードの解説の記事はあまり見なかったので参考になれば幸いです。

https://qiita.com/1zushun/items/1e7a833be4a4402f2b74

今回のアプリ開発で使用したパッケージ達の紹介をしています。こちらもあまり見たことがないような気がしたので取り上げました。

https://qiita.com/1zushun/items/fe2c1d926d366e596f3a

## ■ Firebase編

Firestoreの入出力に型定義をつけるためwithConverterを使ったのですが、公式コードをそのまま使うと肥大化してしまうので、コンパクトにまとめて使いまわせるようにファイルに切り出した記事です。

https://qiita.com/1zushun/items/e469dff8b969690f8972

先のreact-tinder-cardの実装に関係している記事です。どうやらランダムでFirestoreからデータを取得はできないようで、その実装方法についての内容になっています。

https://qiita.com/1zushun/items/20c495daa72ce6b596cc

## ■ Stripe編

Firebaseの拡張機能「Run Payments with Stripe」を導入した後についてまとめた記事です。

「管理者がアプリ画面から商品をStripeに登録する」実装と「ユーザーが商品を選択して購入する」実装の解説をしています。他の方がすでに残している「Run Payments with Stripe」の導入記事と合わせれば簡単に実装できるかと思います。

https://qiita.com/1zushun/items/6934f509345a0667100d

https://qiita.com/1zushun/items/1f9e77ca91ac8211d28b

# 実装し切れなかったところ

・購入周り全般の機能不足（購入後のメール通知、いつ商品配達をするのかなど）
・診断結果の実装(どのようにユーザの好みにカスタマイズしていくかのロジックなど）
・細かなバリデーションの追加（できればFirestore rulesにもっと触れたかった）

他にも探すと色々あるのですが、完成とはほど遠い…

# 実装してみての所感

やはり時間が足りない。引き出し（実装経験）の狭さを痛感しました。そのため初めて実装するという壁に直面し調査から入る必要があったりして、そもそもコードを書き進める以外のところで時間が取られることがしばしば。全体を通して開発は難航しました。

## ■仕様決め、デザインの重要性がわかった
何も定義されていないアプリ開発は本当に大変だなと思いました。デザインが決まっていたり、開発すべき機能が決まっていたり、それだけでも全体の見通しが違うなと思います。

開発する身として事前にデザイナーさんがシステムのデザインを、PMが仕様を落とし込んで方針をたてて下さっているありがたみを身をもって知ることができました。

特にデザインに関しては何度も変更をしてしまいデグレったり、しょっぱなのワイヤーフレームなども中途半端に作ってしまったのが裏目にでて、毎回出たとこ勝負になり、ひと段落するまで遠回りをしたなと思いました。

## ■UIの実装を適度に進める、もしくはコミュニケーションを密にして心配させない

週１程度で友人に進捗報告していたのですが、あまり画面作成や機能実装が進んでいないタイミングでjsxからtsxに変更する作業やCSSモジュールをITCSS, RSCSSに移行する作業をしてしまい、友人にとっては実装が止まっているかのように見える期間がありました。

実装者視点から見ると進捗はあるのですが、改めて振り返ってみると友人は「実装進んでいるのかな」と不要な心配をさせてしまったのではないかと思いました。（思いすぎでしょうか…？）

本当に所感ではありますが、これは実務でも通ずるところがあるのかなと思いまして。PM（今回は友人）から見ると何をしているのわかりにくい部分もあると思うので、最低限PM（今回だと友人）が安心できるぐらいのUIの実装は進める。そもそも今、本当にリファクタが必要なのか検討する。もしくはリファクタをすることで得られるメリットなどを話しコミュニケーションを密にする必要性を感じました。

## ■一次情報（OSSのデモコードや公式ドキュメント等）を見る癖をつける

例えば決済機能をFirebaseの拡張で実装したい場合、調査をするとサーバー側のStripeの実装記事、フロント側でのStripeの記事、Firebaseの拡張機能のStripeの記事（そもそもFirebaseのバージョンが異なっていたり）など欲しい情報を見分ける必要があります。

自分も同じ壁にぶつかり、最終的には公式ドキュメントを見ながら実装を進めていきました。また、react-tinder-cardに関しては情報自体が乏しかったのでOSSを見て実装しました。

実装記事を参考にするのは便利な反面、断片的で実装してみたら噛み合わなったり、実装の記事すらない可能性もあるので一次情報を確認する必要性を感じました。特にOSSに関しては自分のコードのバリエーションが増える恩恵もあるので実際にコードを追ってみるのがおすすめです。

# さいごに

3ヶ月で0から新しい技術のキャッチアップをし形に落とし込めるかの確認もできましたし、実装したことのない機能の開発経験も得ることができました。また、テマナシーをこうやって記事として公開し日の目を浴びさせることができたので2月末をもってこのアプリの更新は止めようと思います。

いろいろあって3月からはSvelteのキャッチアップをする予定なので、そちらに時間を割いていきます。駆け足になりましたが最後にアプリ開発を持ちかけてくれた友人、レビューに付き合ってくださった先輩社員に感謝いたします。ありがとうございました。