未経験から2ヶ月のインターンで、React × Next.js × Firebaseでサイトを作った話

##はじめに
こんにちは、[@takashima_katsu](https://twitter.com/takashima_katsu)です！

実務未経験からインターンとして[株式会社m-Lab](https://m-lab.inc)にジョインし、2ヶ月が経ちました。

[弊社のコーポレートサイト](https://m-lab.inc)を、Next.jsとFirebaseで実装したので
その時に得た知見をまとめてみました。

##2ヶ月前のわたし
**独学で、Reactを2ヶ月ほど学習**

- Reactチュートリアルやったよ！
- Reduxなにこれ？必要！？
- ReactかいてるけどJavaScriptわかんない...
- CSS？ よくわかんないからBootstrap 使うー

こんな私を拾ってくれてありがとうございます。(陳謝)

##使用技術
- React 16.8.6
- **Next.js 6.1.2 (理由は後述しますが、途中までは8)**
- Firebase
    - Firebase Hosting
    - Cloud Functions

##開発の流れ
**開発は私1人**

とりあえず調べながら作っていく
↓
詰まったら質問
↓
機能ごとにプルリクを出す
↓
コードレビューをもらう
↓
修正

の繰り返しです。

デザインはすでに用意されており、それを見ながら作っていきます。
細かいところなどは、デザイナーさんと都度すり合わせながら作っていきます。

##実装
特に勉強になったところをまとめています。
###Reactでアニメーション実装
スマホ版では、左上のハンバーガーを押すとメニューが出てくるようにしているのですが
![株式会社_m-Lab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231184/b3cf542e-82e0-27cd-077a-fa02e9da9033.png)

デザイナーさんからの要望で
出てくる時にフェードをかけたいとのことだったのでアニメーションをつけることにしました。

↓実装済みがこちらです
<a href="https://gyazo.com/a9f36503ee979339f140e1f3fb7d803c"><img src="https://i.gyazo.com/a9f36503ee979339f140e1f3fb7d803c.gif" alt="Image from Gyazo" width="406"/></a>
(わかりづらいですが、一瞬フェードイン、フェードアウトしてるんです。笑)

Reactでのアニメーション実装は[**react-transition-group**](https://github.com/reactjs/react-transition-group)を使いました。
このモジュールで**ReactでCSSアニメーションを使う**ことができます。

公式が多くのテンプレートを提供してくれてるので、
そこを参考にしながら、自分好みにカスタマイズできると思います。

###お問い合わせをSlackに流す
**SlackAPIとaxiosを使い、弊社Slackのお問い合わせ専用チャンネルに下記のように送られるようにしました**

↓全て記入すると
<img width="600" alt="スクリーンショット 2019-07-16 17.55.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231184/0f665b60-14ff-2d56-135c-fae6af025bef.png">
↓こんなふうにSlackに送信される
<img width="600" alt="スクリーンショット 2019-08-08 16.24.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231184/0737779c-c636-3b18-1f03-8c407e20b8eb.png">

具体的には、各々の入力情報をstateとして扱い(Hooksを利用しています)

```javascript
const [values, setValues] = useState({
  name: '',
  kana: '',
  corporate: '',
  mail: '',
  tel: '',
  message: ''
});
```

送信ボタンを押した時に、Slackへ送信されるためのイベントを発火します

```javascript
const handleFormSubmit = async () => {
  await axios.request()
  Router.push('/thanks')
}
```

###SASSとBEM
**CSSはSASS化させ、BEMによるCSS設計で書きました**
両方とも初めて使ったのですが、可読性をあげすっきりとしたコードにするためには必須だと感じました。

特にBEMは途中から導入したのですが
最初の頃に命名規則的などを分かっておらず、色々なところでが競合が発生していたのが解決した時は感動しました。

BEMを知らない人に説明するのには、かなり奥が深く難しいので他の記事に任せますが、
個人的に良いなと思ったのは、**クラス名だけで構造がわかる**ようになるところです。

↓例えば、こちらのBEMを利用したクラス名は

``form__button--disabled``

- フォームの
- ボタンが
- 無効な時

と、一目で
どこの、どの部分が、どういった状態なのかを把握することができます。

↓こういった感じで書くこともできます

```scss

.form {
  color: #fff;
  width: 100%;
  &__button {
    width: 40rem;
    &--error {
      background-color: #ccc; 
    }
  }
}
```
かなりスッキリと書けますね

###IE対応
VirtualBoxに仮想環境を立て、スタイルの修正をしました。
**IE滅べ以外の感想は特にないです**

###Googleアナリティクスの導入
サイト分析ツールとして[Googleアナリティクス](https://analytics.google.com/analytics/web/?hl=ja#/report-home/a125424804w183987711p181429033)を導入しました。

Next.jsにGoogleアナリティクスを導入方法を調べたところ、候補としては以下の4つをみつけました。

- analytics.jsの追加
- gtag.jsの追加
- react-gaの追加
- next-gaの追加

**採用したのは、[next-ga](https://github.com/sergiodxa/next-ga/blob/master/package.json)です**

理由としては、
analytics.jsとgtag.jsはSPA対応がなんとなく面倒臭そうなので不採用
react-gaはissueにNext.jsでも使えるようなことを見たが、あくまでもReact向けのなので不採用

next-gaを使ったGoogleアナリティクス導入はかなり簡単です。

####1. next-gaをインストール

```bash
$ yarn add next-ga
```

####2. カスタムAppをラップする
```_app.js
import React from 'react';
import App, { Container } from 'next/app';

//以下をインポート
import Router from 'next/router';
import withGA from 'next-ga';

class MyApp extends App {
.
.
.
.

//export default MyApp　ではなく
export default withGA('UA-*********-1', Router)(MyApp)

```
[公式](https://github.com/sergiodxa/next-ga)の通りです
簡単に導入することができました。

###Firebaseを使ったデプロイ
最もハマったところです

- Firebase Hostingで静的ファイルをホスティングして
- Cloud Fonctionsでバックエンドコードを実行しました

**結論から書くと、FirebaseがNext.js8に対応しておりませんでしたのでNext6.jsまで下げてデプロイしました。**

↓サポートに問い合わせた返信です
***
![farebase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231184/eb326a15-6f8d-870a-4694-2a31ea013c28.png)
***
※Next.jsのFirebaseデプロイ方法に関しては長くなるので、別記事にまとめてからリンクを貼ります。

ここではかなり長い間詰まってしまい、代表に相談した結果、
`そもそもサポートされていないのでは？`という疑問が生まれ、
サポートに問い合わせると上記のような返答が届きました。

代表が調べている間、横でただただ傍観していることしかできなかったのですが、
私では追えなかったよう、`node_modules`内などの深いところまで追って調査しており、
実際のベテランエンジニアがどのように調べているのかを見ることができたので、勉強になりました。

この部分では、結果的には他の人の手を借り、自己解決をすることができなかったのですが
**・自分で調べる力**
**・コードの深いところまで見る力**
を少しでもつけれることができました。

そして何よりも**自分自身がわからないことに対して、根気強く調べることができる人間**
だということが知れたのが大きかったのかと思います。

これからエンジニアという仕事をやっていく中では、何度も未知の技術に触れていくことがあると思うので
これに対して楽しむことができることを早期に知れたのは、技術の習得以上に重要なことになったかも知れません。(知らんけど)

##最後に
冒頭に書いたことからもわかるように、本当に**よちよちレベル**からのスタートでした。

ですので正直な話、いきなり1人で任せられた時には、かなり不安でした。笑
(もちろん毎日質問、毎日コードレビューして貰って修正の繰り返しです)

ですが、**自分でポートフォリオも作ったことのない状態で入らせて貰った私としては
初めて作った成果物なので**、できた時の達成感はもの凄いものでした！(語彙力...w)

**それに当たり前ですが、独学でやっていた時よりも周りに聞ける人もでき、多くのことを吸収できるのではるかに楽しいです！**


そして、次からは自社サービスの開発に入っていきます。

**クラウド型の広報(PR)サービス**を作っているのですが、
フロント(React)とインフラ(Firestore)辺りを担当させていただくことになりそうです！
~~(AIを使ったサービスなので、個人的には機械学習領域も気になっていますw)~~

まだリリース前なのですが、毎日のようにサービス案を出しては議論をしているので、
おもしろそうなサービスの開発には入れそうで楽しみです！笑

もし気になった方は、事前登録もしており無料枠もありますので、覗いてみてください！

[HARVEST](https://harvest.site/)
<img width="400" alt="スクリーンショット 2019-07-17 2.42.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231184/e1b4f283-0d61-e0ce-bf46-7c244c1a34c6.png">
また**Webデザイナーのインターンも募集しています**ので、一緒に働いてみたい方がいましたら[Twitter](https://twitter.com/takashima_katsu)のDMにてご連絡ください。

最後まで読んでいただきありがとうございます！