ゆめみさんのフロントエンドコーディング試験の胸を借りる1週間
動機
現在就職活動中です。しかし「何が出来ますか?」と聞かれると自信がなくなります。
仕事中の気になった点や個人的に学んだことを記事に書いたりサンプル実装をすることはありますが、まとまったアプリケーション単位で作ることがなかったので、ゆめみさんの採用試験の内容をもとに自分の考えとともに、まずやり終えてみることを目指したいと思いました。
迷惑なら消します。
試験内容
当然ですが制約は試験内容に準拠します。
期間に関しては経験者として1週間、仕事と生活とダイエットの合間にやります。←ここ言い訳ポイント
作業開始と進捗と終了はこのスクラップで報告します。
1日目(0:00を回ってしまったので本来は水曜ですが火曜日はじめにします)
まずは内容の確認です
気になった点
- ワイヤーフレームと内容を見る限り、ロジックとしてはAPIを呼んでフォームのイベントを拾ってグラフライブラリを使って描画する、というシンプルなもの
- レスポンシブそしてモバイルファーストが求められている
- CSS/UIフレームワークの使用は禁止。CSSが書けることを求められている
-
リードエンジニア・テックリード
の制約も盛り込んでおく
大事だなと思った点
- 期間は絶対。1週間でデプロイと作業まとめまでやる
- 外部API +
セキュリティを考慮して...
= つまりAPIキー隠し - モバイルファーストのCSS設計
- チーム開発での考慮
- どんなことを指すかあまり想像できてない。コミットをちゃんと分けるとか?
やったこと無い(時間が吸われそう)点
- モバイルファーストなCSS設計
- 手探りでやってみる
- RESAS API
- React/Vueアプリのホスティング
- そういえばなかった。Angularならあるから多分大丈夫
1日目作業報告
- RESAS APIキーを取得
- プロジェクト雛形作成
- Github公開リポジトリへの登録
- リモート環境へのデプロイ
- 作業時間: 3時間10分
2日目作業予定
- RESAS APIの仕様確認
- CSS設計を考える
- コンポーネント実装
以上、おつかれさまでした
- RESAS APIキーを取得しました
次に利用技術を考えます。
現在仕事でよく使うVueを使います。
ビルドツールはViteを使います。Webpackの方が使い慣れていますがViteに慣れたいので
幸いViteはTypescript×Vueのテンプレートがありますので、それを利用します。
npm create vite@latest yumemi-frontend-test -- --template vue-ts
作成されたボイラプレートから不要なコードを削除します。
ついでに使い慣れたCSSプリプロセッサとしてsassを採用しresetCSSを追加しました。
コンポーネント表示物をタイトルだけの簡単なものにして、まずはデプロイを優先します。
一旦は何も考えずにGithubPagesを使います。
Viteの手順に則ります。最終的に変更するかもしれません。Githubの公開リポジトリ: https://github.com/michihiko-karino/yumemi-frontend-test
Github Pages: https://michihiko-karino.github.io/yumemi-frontend-test/
...VIte公式の方法がうまくいかないのでgh-pagesを利用します
と思って試していたのですがなぜかうまくいかず…
ただのリモートでの確認のためが1時間以上もたもたしてしまいました…
これは単純に私がGithub Pagesをあまり使ったことが無い知識不足からくるものです。
諦めてPagesの設定をmainブランチの/docs
フォルダを見てもらうことにして、Viteの成果物をgit管理することにしました。今後の課題としておきます。
2日目開始です(0:10)
本日の作業予定は以下の通りです
- RESAS APIの仕様確認
- CSS設計を考える
- コンポーネント実装
まずはAPIを叩いて動くSpike実装を作ります
Spike実装を作る前にESLintとPrettierを導入します。
個人的な考えですが、この2つはついていくのが辛い…、死に設定が多かったり、新しい設定を導入するかどうか悩む…のであまり深く考えないでググって更新日が新しいものを参考にすることが多いです。
ただチーム開発が前提にある場合はメンバーで相談したりしてなるべく最新を追うように心がけたいなというきもちです。
今回は↓の記事を参考にしました
私は行末セミコロンだけは絶対つけたい、それ以外はデフォルトやプロジェクトの好きなように、という牧歌的・日和見派なので、セミコロンだけを有効にして他の設定は真似をしました。
ローカルでRESAS APIで都道府県APIを叩き、レスポンスを画面表示する。チェックボックスを表示して選択値を表示するところまで実装しました。
リモート上ではまだ確認できません。現状RESASのAPIキーを隠しながら公開することができないからです。
HTTP Clientライブラリには使い慣れたaxios
を使っています。
引き続き、総人口APIを叩きChartに折れ線グラフを描画するところまでSpike実装を作ってしまいたいですが、今日は眠いので切り上げます。
2日目作業報告
- RESAS APIの仕様確認
- CSS設計を考える
- コンポーネント実装
- ESLint,Prettierの導入
- APIキーをdotenvから取得するように変更
- Spike実装: 都道府県を表示・選択できるようにするまで
- 作業時間: 2時間30分
3日目作業予定
- Spike実装: 総人口APIを叩き折れ線グラフを表示する
- CSS設計を考える
- テストを実行できるようにする
- アプリ全体のコンポーネント設計を考える
以上、おつかれさまでした〜
3日目開始です(23:30)
今日は眠いので1時間30分で切り上げます。
本日の作業予定
- Spike実装: 総人口APIを叩き折れ線グラフを表示する
- CSS設計を考える
- テストを実行できるようにする
- アプリ全体のコンポーネント設計を考える
総人口APIの仕様書
仕様を見ると県コードは一つずつしか指定できないようです。
よってチェックボックスをクリックしたら総人口APIを呼ぶような作りになりますね。
県の総人口というのはそうそう変化する値ではない(実際には頻繁に変わっているでしょうが)ので、一度APIを呼んだ県はそのレスポンスを保存しておいて無駄なリクエストをへらすと良さそうですね
一旦Spikeなので深く考えずチェックされたらAPIを呼ぶように実装してみます。
chartjs
を使って描画してみました。
またVue用のchartjsラッパーとしてvue-chartjs
も使いました。
datasetsとして渡す配列が空の場合グラフが表示されない、強制的に表示する方法も分からなかったため、一旦こちらはあきらめました。
現状未実装で解決すべきところをまとめます。
- 総人口APIのレスポンスをキャッシュできるようにする
- チェックを外した時対応する折れ線グラフを非表示にする
- それぞれ折れ線の色が固定
一旦最低限の依存ライブラリと必要実装が分かったためSpike実装は終了します。
ちょっと進捗が悪いですが残業しちゃってるので上がりましょう。
...各都道府県の人口推移予想値がガクッと下がる感じを見てびっくりしました…。
3日目作業報告
- Spike実装: 総人口APIを叩き折れ線グラフを表示する
- CSS設計を考える
- テストを実行できるようにする
- アプリ全体のコンポーネント設計を考える
- 作業時間: 2時間50分
4日目作業予定
- CSS設計を考える
- テストを実行できるようにする
- アプリ全体のコンポーネント設計を考える
一応Spike実装のコード差分のリンクも載せます
作業進捗と作業予定を残しているのは、これぐらいならイケるかな?的な打算で書いているだけなので大きな意味はないです。
ただチームとして作業する場合、進捗と自分の予想は当然持っている方がいいので書いています。
デプロイ関連作業は落とし穴が多いので2日分の作業日を設けておきたいです。
そうなると大方の実装を5日目までで終わらせてしまいたいですね。
もし間に合わないとしたらですが、汚く実装しても早くなる訳ではないので、削れる作業としたら総人口APIレスポンスのキャッシュであったり、初期描画時にグラフがレンダリングされない問題だったりでしょうか。
一旦そのような作業はリファクタ作業としてデプロイ後に着手するといいでしょう。
4日目開始です(0:20)
今日の作業予定
- CSS設計を考える
- テストを実行できるようにする
- アプリ全体のコンポーネント設計を考える
まず進捗の出せそうなテスト実行について考えてみます。
せっかくViteを使っているのでVitestを使ってみます。初使用です。
ちょっと初めてなので手間取りましたが出来ました。
簡易なテストも追加・実行して問題なしです。
次にCSS設計について考えていきます。
私は、CSSをJSの世界に持ち込んだりすることにまだ利便性を感じたことがないので今回もそこらの技術はつかいません。
今回の規模のアプリであればCSSに悩まされることは逆に難しいと思いますが、ある程度の大きさになるとつらみにはまることは知っています。
しかしviteのCSSのセクションを見るとSassも使えるけどPostCSSをつかった方がいいよ、と書いてあるので前工程でSassを導入してしまいましたが、PostCSSオンリーに変更しようと思います。
postcssに切り替えて、さてCSSの骨組みを考えていたのですが疲れからか吐き気を催してきたので今日はもうお休みです。
4日目作業報告
-
CSS設計を考える
- sassではなくpostcssに切り替えた
- テストを実行できるようにする
- アプリ全体のコンポーネント設計を考える
- 作業時間: 1時間40分
5日目作業予定
- CSS設計を考える
- アプリ全体のコンポーネント設計を考える
- 詳細実装
作業が押していますね。まあなんとかなります
5日目開始です
今日は休日ですので時間を分けて何回かやると思います。
まず17:50から
作業予定
- CSS設計を考える
- アプリ全体のコンポーネント設計を考える
- 詳細実装
CSS設計を考える
ですが以下のようにしました。
- 基本的にコンポーネントのScopedStyleにCSSを書く
- 共通のCSSを持ちたい場合
src/style.css
にまとめる
CSSをVueやReactといったJSフレームワークと一緒に使うとき選択が特に難しいと思います。
私はデザインに責任を持つ人とUIのロジックに責任を持つ人はほとんど場合分かれていると考えます。
なのでデザインに責任を持つ人は最低限HTMLとCSSを適切に設計してくれてコンポーネント単位でガイドラインを作っていただければ、後は私のようなUIロジックに責任を持つ人が適切にコンポーネント化していけばよいと思います。
そうなるとCSS in JSの手法は採用しにくいのでCSSを書く部分がはっきりしていて通常のCSSらしいCSSが書けるScopedStyleがいいと判断しました。
ただアプリ全体で共通して持ちたいStyle(例えばbody
とか)は当然あるのでそういうものをまとめる一つのCSSファイルを置くようにしました。
アプリ全体のコンポーネント設計を考える
ですがワイヤーフレームを見ると大きく分けて3つの要素があります。
- タイトル
- 都道府県選択
- グラフ
タイトルはコンポーネントにするほどのものではないと判断したので2つのコンポーネントが必要ですね。
2つのコンポーネント間で連携して動作させるためのストア実装も必要です。
前回Spikeを作った時にAPIレスポンスをキャッシュさせる仕組みもストアの機能に入れてしまえそうですね。
コンポーネントの設計はあまり難しくなさそうなのでストアの詳細を考えてみます。
ストアのstate
- 都道府県APIから取得した名前とコードのセット
- 選択している都道府県コードの配列
- 県の総人口を置いておくデータセット
- グラフに渡すデータセット
ストアのmutation
- initialize(都道府県APIフェッチと各データセットの初期化)
- 選択している都道府県コード配列を書き換える
- 総人口APIを取得しデータセットを書き換える
- グラフに渡すデータセットを書き換える
実際にコンポーネントから実行されるのは 選択している都道府県コード配列を書き換える
mutaitonですが、テストを考えるとこのような感じになりそうです。
一旦作業中断です。19:30
作業再開です。0:10
考えた設計に沿って詳細実装していきます
API Clientモジュールとそのテストを追加しました。
ストアの詳細実装を進めていたのですが疲れたので切り上げます。
5日目作業報告
- CSS設計を考える
- アプリ全体のコンポーネント設計を考える
-
詳細実装
- APIクライアントモジュールの追加まで
- 作業時間: 3時間30分
6日目作業予定
- 詳細実装
- APIキーの隠し方を考える
- デプロイ
Spikeがあるので追加の対応以外はあまり悩まず詳細実装を進められています。
6日目でもろもろ終わりそうな気がしています。
お疲れ様でした〜
6日目開始です(12:50)
詳細実装を続けていきます。
入退出しながら6時間ほど作業しました。
モバイル
PC
テストも実装済みです、
一旦退出し、APIキーを隠す方法とデプロイ先をさがします。
再開です(0:40)
APIキーを隠す方法はProxyServerを立てるような感じで行こうとおもいます。
これはあくまでRESASから私のアカウントに付与されたキーを他社に盗まれない方法でしかなく、ProxyServer経由でRESASへのアクセスが成功してしまうため、結局はいくらでもAPIを叩くことができます。
これを防ぐためにはそもそもログイン機能をつけるなどの方法しかないと考えます。
一旦は外部APIキーを隠すことでセキュリティを担保した…ということにしておきたいです。
ググるとピッタシな記事がヒットしましたのでこちらを参考に進めていきます。https://zenn.dev/mr_ozin/articles/17920ca403b8af
この記事の通りでいけばデプロイ先はVercelになりますね。
vercel serverless functionにてRESAS APIを叩くところまでを確認できました。
あとは既存のViteアプリのAPI ClientをVercel側に依存するように修正して、vercelにViteアプリをデプロイして完了になります。
VercelとViteの連携は何も考えなくとも終わったので、最初からこちらにしていればよかったですね。
明日の作業とし6日目は終了とします。
6日目作業報告
- 詳細実装
- APIキーの隠し方を考える
-
デプロイ
- vercelで問題なくデプロイできそうなことが分かった。vercelさまさま
- 作業時間: 8時間
7日目作業予定
- デプロイの完了
- 最終成果物へ向けたお掃除
- 作業時間のまとめ
- このスクラップのクロージング
7日目開始です(11:30)
- デプロイの完了
- 最終成果物へ向けたお掃除
- 作業時間のまとめ
- このスクラップのクロージング
viteとvercelを連携させるときのdotenvをどうするべきか考えます
- vite
- https://ja.vitejs.dev/guide/env-and-mode.html#env-files
-
.env
はenvファイルのベースとなる - 各モードを定義できる
.env.production
- 最後が
.local
だとgitignore
される
- vercel
- https://vercel.com/docs/concepts/projects/environment-variables
- projectのsettingsのenvironment variablesから設定できる
- それとは別に
.env
からも読み込まれる
なので秘匿の必要のない環境変数は.env
に定義して秘匿する変数は
- ローカル開発では
.env.local
に - リモート環境には手動で
登録すればいいことが分かりました。単純ですね
最終的に
.env
ファイルはgitignore
に、本番・開発ビルドで分けたい環境変数であるVercelServerlessFunctionsのエンドポイントのパスは .env.development
, .env.production
にそれぞれ定義して実現しました。
一度Github Pagesにデプロイした時の差分の削除
npm run scriptの削除など
を実施して実装終了とします。
7日目作業時間: 2時間
作業時間まとめ&クロージング
GitHub の public リポジトリの URL をお知らせください。
課題の取り組み開始から完了までに要した合計時間
これまでの総合的なプログラミング歴
これまでのWEBフロントエンドプログラミング歴
- リポジトリ: https://github.com/michihiko-karino/yumemi-frontend-test
- 合計時間: 23時間40分
- 総合的なプログラミング歴: 学生時代も合わせると9年(職歴としては7年)。詳細は省く
- WEBフロントエンドプログラミング歴: 5年ほど?。詳細は省く
感想
最初に課題を見た時にシンプルな課題だったので挑戦してみました。
使ったことがなかったツールも多かったですが、大体どん詰まりすることなく実装できたので助かりました。
特にViteとVercelのデプロイが簡単でした。
最初何故かサブディレクトリをVite上のプロジェクトルートに設定していたのでVercelへのデプロイ時にうまく動かずうーんうーんとなりました。サブディレクトリを辞めたらすっといきました。Vercel最高
なにか自分で作りたくなったときも今回の採用技術を使いたいなと思いました。
普段はWebpackでビルドしているのですが、やはりViteはいいですね。早いは正義
Vue実装についてはごくごくシンプルに実装できたかなと思いました。
provide/injectを使った簡単なストア実装で状態管理しましたが、テストでモックするのが少し大変でした。
実装自体はシンプルでよかったかなと思います。
1週間で終わらせるという目標については、1週間の単位を5日と見るか7日と見るか、1日を何時間で見るかで迷いましたが、ここは人それぞれなのでリアルタイム1週間としました。
仕事でやるならもうちょっと早く終わらせたいですね。
以上