データサイエンティストがフロントエンド 入門がてらReact + typescriptでWEBアプリを作ってみた

## 概略
普段フロントエンドに一切タッチしないデータサイエンティストが、フロントエンドの勉強をしてアプリを公開してみたので備忘録を残してみる。

## 作ってみたもの
画像のアノテーションツール。アノテーションを行いたい画像URLの一覧と画像パーツの候補ラベルの一覧をjson形式のファイルでアップロードし、ブラウザ上で画像にバウンディングボックスを引き、それぞれのボックスにラベル情報を選択して与えるというもの。
これがサービスのリンク。
[Image Annotator](https://image-annotator-elizabeth.herokuapp.com/)

下記の画像のようにバウンディングボックスごとに登録しておいたラベルを結びつけることができる。また、画像ごとにメモも残せる。画像群のアノテーションが終了したら結果をexportでき、全てのバウンディングボックスの画像内での座標とラベル、メモがjsonファイルに出力される。
<img width="1440" alt="annotation.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122985/8ee9c2d8-17cc-d53c-beca-0d117860b61a.png">


## 動機
普段はブラジル、サンパウロでデータサイエンティスト/機械学習エンジニアとして働いており、データトランスフォーマーのロジックを書いたりモデルを作ったり、デプロイに苦戦したりしている。私生活でも、論文を読んだり、時々実装したりしているのだが、ユーザーを想定した開発は行っていない。個人的に、毎年少しずつでも自分の分野から離れたものを学んでいきたいと思っているので今回はフロントエンドにタッチしてみようと決めた。今年中にもう少しDevOpsよりの知見も深めたいところ。
先日、第一子が生まれ、育児休暇もあるので、育児しがてら進めてみた感じ。

## 作ってみるにあたって
作成期間が育児休暇であるため、そんなに時間はないし、正直、フロントエンドはほぼ何も知らない状態だったので、目標は低く設定した。

* 機能は少なく
* デザインはウルトラシンプルに
* 最新の技術に拘らず
* デプロイ優先

収益化などを考えてるわけではなく、限られた時間での入門、勉強が目的なので何よりもデプロイを優先して、後に繋げることを目標に設定。

## 制作過程

## 勉強段階
普段は、公式ドキュメントや論文などの読み物中心でインプットを行うのが好きなのだが、今回は趣向を変えて動画コンテンツを進めてみた。
Udemyで以下の二つのコースを取って、動画速度を二倍速にして一気に試聴。

* [The Web Developer Bootcamp](https://www.udemy.com/course/the-web-developer-bootcamp/)
* [React - The Complete Guide (incl Hooks, React Router, Redux)](https://www.udemy.com/course/react-the-complete-guide-incl-redux/)

動画のように時間をコントロールしにくい媒体はあまり好きではないけれど、上記の二つは結構良いコースだったと思う。ちょっと、冗長にも感じた。
個人的にはやっぱり、公式ドキュメントなり書籍なり読んだ方が楽だったとは思う。

HTML操作、jQuery、Reactと進めていって漠然と感じたのは（多分全く正確じゃない）

```
HTMLの操作勉強時: 『フロントエンドって結局HTMLをひたすら操作してく感じ？？』
↓
jQueryの勉強時:　『DOM操作が楽になる感じ？？Stateの管理とそれに合わせた画面描写管理がまだ課題？？』
↓
Reactの勉強時: 『Stateやrenderの前後での操作を定義できて全体的に管理が楽になる感じ？？』
```

くらいに漠然とそれぞれの必要性を捉えてた。

### 開発段階
そのあとは、一気に開発。困ったのは、『作りたいものがわからない』という点だった。学習を踏まえた初手なのであまり複雑なものは避けたいし、フロントエンドにフォーカスしたいので今回はバックエンドが複雑になるものもパス。
そういえば、何かと画像アノテーションを行う必要がたびたびあって、その度に場当たり的に対応してるなーと思ったので、今回は画像アノテーターを作成することに決定。
使用する言語は、型がある言語が好みなのでtypescript。

初期段階では、『そんなに難しいものでもないし、セマンティックにコンポーネント分けて、状態を持たせるか決めるだけ』と気楽に進めていた。
実際に進めていくと、なんだかんだで、UIが気に入らずにやり直し。その際の変更に伴い、既存のStateの保持場所だと都合が悪く、Stateの管理を変えたりとなんだかんだで時間を食うというのを繰り返し、三歩進んで二歩戻る感じだった。

地味に一番時間を食ったのはCSSだった。デザインを完全に決めずに漠然と進めたので、『あ、こうしたい』と色々弄ってみるもうまくいかず。結局、全部破棄して考えうる限り最もシンプルな形にした。CSS難しい。

とはいえ、目に見えて動くものを作っていくのはとても楽しかった。

### デプロイ段階
デプロイは比較的楽に済んだ。
以前、Qiitaの記事で[最も低コストでプロダクトを公開したい](https://qiita.com/Taro_man/items/cea8c095fe8680ab12f3)というのを見かけたので、今回はそれを採用。Gitに結びつけてお手軽デプロイ。

## 今回やらなかったこと
フロントエンドに入門して、開発してデプロイまで行ったが、今回、やらなかったこと、問題点はいくつかある。

1. duplicatedなメソッドを使用している
最新のReactでnot recommendedなメソッドを使用してる。後で直す。

2. テストを書いてない
これはよろしくない。フロントエンドでのテストの書き方を調べてなかったので今回はスキップしてしまったが、早めに書き方のキャッチアップをしたいところ。

3. 全体的にvalidationがきちんと書かれてない
inputファイルに対する最低限のvalidationは書かれてるが、ここの画像URLの確認などのvalidationが抜けている。これも書いておくべき。

## 実際に作ってみて
感じたことはいくつかある。
一つ目。流石に、育児休暇中でまとまった時間が取れたとは言えなかったので色々すっ飛ばしながらなので、補完する必要があるなという感じ。
二つ目。プロダクトとして、利益が出るか出ないかという視点で言うと今回作ったものは『箸にも棒にもかからない』のではないかというのが、作成段階で感じたこと。もしも公開するにしても、ソースコードをgithubで公開して、ローカルのファイルをそのままアノテーションできる方が遥かに便利だと思う。次回何かを作るときはペルソナ分析をして、必要にあったものを作っていこうと思う。
三つ目。CSSが難しい。その場しのぎにひたすらググってどうにかしようと思ったが、かなりキツかった。きちんと時間を取って、体系立てて学んでいこうと思う。
四つ目。動くものを作るのはモチベーションが上がって楽しい。業務で使うことはあんまりなさそうだけど、個人的には色々勉強していきたい。
五つ目。デザインって難しい。
六つ目。雑に作ることを良しとして始めたが、実際に雑なものが仕上がると気持ち的には微妙。
七つ目。終盤、色々と失速したので、少し早い段階でデプロイフローを整えた方が多分開発のモチベーションが保てた。
八つ目。今回は動くものを作るのが目的だったためフォーカスはしなかったが、それでも、ユーザーが自然に感じる挙動について考えると色々難しいところがあった。