Nuxtで踏み出すフルスタックエンジニアへの道

この記事は[Nuxt.js Advent Calendar 2018](https://qiita.com/advent-calendar/2018/nuxt-js)の11日目です。

## この記事の内容
- プロダクトのプロトタイピングとフロントエンドエンジニアの価値について
- Nuxt.js×Express×MySQLのアプリケーションテンプレート[nuxt-full-stack-template](https://github.com/gyarasu/nuxt-full-stack-template)のご紹介

## 関連情報
本記事は、2018/10/18に開催された[NuxtMeetup #5での発表内容](https://speakerdeck.com/gyarasu/hurontoendoenzinia-shi-jia-dong-made-hitoridedekirumon)を基にした記事となっております。
また、Nuxt関連でアドベントカレンダーの記事を2つほど書いているので興味のある方は合わせてご参照ください。

- [Nuxt × PWA × CDNでハマった件について](https://qiita.com/gyarasu/items/005e4c74fa166d048dbe)
- [【Nuxt.js】pwa-moduleのちょっとしたTIPS](https://qiita.com/gyarasu/items/b5c34b6aac02cb325b79)

## 新規サービスのプロトタイピングとフロントエンドエンジニアの価値について

### 「企画を通す」ことと、「プロトタイプ」を見せること
組織文化や規模、人員構成によって状況は異なりますが、例えば人数が多い事業会社において考えた企画を通すことは、いろんな人の承認を得る必要があって結構大変だったりします。
そこで役に立つのが「プロトタイプ」です。百聞は一見に如かず。事業としての狙いやKPI等を説明するためにはパワーポイントでいいのですが、実際にどんなサービスで何ができてどんな動きをするのかを説明する際に、ワイヤーフレームだけだとなかなか伝わらないことがあります。

### ホンモノに近いプロトタイプの追求
プロトタイピングツールは様々なものがありますが、現場レベルで役立つものと経営層への説明に役立つものは異なると個人的には考えています。例えば現場のディレクター・デザイナー・エンジニアの間ではペーパープロトタイピングで十分会話ができることが多いのですが、経営層（もしくは事業判断の意思決定権を持つ層）とペーパープロトタイピングを通して濃度の高い会話ができるとは限りません。
ホンモノっぽいプロトタイプ（実際に画面があって、触れて、動く）ものがあるほうが圧倒的に伝わりやすくなります。

### プロントエンドエンジニアの強み
本格的に開発を進める前にあるハードルに直面した時、「作ってしまえる」という部分においてフロントエンドエンジニアの強みがあります。デザインや裏側の仕組みはいったん置いておき、より手触り感のあるプロトタイピングとしてフロントエンドを実装すると、関係者の理解度を一気に深めることができ、プロジェクトも加速します。

### プラスアルファの価値
ガワを作ることで企画としてGoが出たあとに課題になるのが、開発リソースの確保です。これは組織次第なのですが、事業会社のエンジニアは実際のところ「リソースを余らせている」ということはあまりありません。既存の担当プロジェクトもある中で関係者と調整したり、評価や期初の目標も絡んでくることがあります（悲しいかな）。

やるときまれば早くリリースしてユーザの反応を見ていきたい（PoCをまず成立させたい）のですが、いろんなプロジェクトでエンジニアリソースの取り合いが起こってしまうとなかなか開発を進めることができません（僕の経験上、それなりにあります）。

人員が少なかったりリソース調整に難航している状況で、フロントエンドエンジニアが守備範囲を広げてPoCが成り立つレベルのフルスタックレイヤーでの開発ができると、デリバリー時間やコスト面での大きな貢献につながります。

## Nuxtベースのフルスタックアプリケーションテンプレート「nuxt-full-stack-template」
それらしいことを書いてきましたが、「役に立つかもしれないものを作ったからちょっと見てほしい」という話でしかありません（笑）。
[nuxt-full-stack-template](https://github.com/gyarasu/nuxt-full-stack-template)というアプリケーションテンプレートを作りました。

基本的には[README](https://github.com/gyarasu/nuxt-full-stack-template)にすべてまとめてありますが、かいつまんで説明していきます。

- シンプルなアーキテクチャ（ゆえに小規模アプリケーション向け）
- Javascript完結
- 特定のクラウドサービスに依存しない

特徴としてはこのような感じで、とりあえずユーザに触ってもらいフィードバックを得られるものを少人数（もしくは1人）でスピード感をもって作るのに適しています。
サービスのグロースや技術選択方針、人的リソース、エンジニアのスキルセット等の状況に応じて、バックエンド側の仕組みは捨てて別の言語やフレームワークで作りなおすといったことも可能かと思います。

### アプリケーションテンプレート概要
![template.gif](https://qiita-image-store.s3.amazonaws.com/0/29971/a800f9c9-0669-2cc0-4a7c-950b919cb92a.gif)

このアプリケーションでは次のことができるようになってます。

- ログイン画面の表示
- ログイン操作
- ログイン後の画面に最終ログイン日時を表示

これだけです。
Nuxt.jsの公式ドキュメントにある[認証ルート](https://ja.nuxtjs.org/examples/auth-routes/)がそのまま含まれています。
MySQLを使ってセッション管理をしたり、最終ログイン日時を保持したりしています。

### バックエンドの仕組み
バックエンド（APIサーバ）に含まれるものと簡単な説明です。

|名前|用途|URL|
|:--|:--|:--|
|Express|Nodeアプリケーションフレームワーク|https://expressjs.com/ja/|
|mysql|DBとの接続|https://github.com/mysqljs/mysql|
|express-mysql-session|MySQLでのセッション管理|https://www.npmjs.com/package/express-mysql-session|
|log4js-node|ロギング|https://www.npmjs.com/package/express-mysql-session|
|config|環境ごとの設定ファイル|https://github.com/lorenwest/node-config|

その他、お手製のサンプルのAPIとエラーハンドラもあります。


### MySQLコンテナ
このアプリケーションテンプレート向けに、[MySQLのDokcerコンテナ](https://github.com/gyarasu/mysql57-docker)を用意しています。
アプリケーション側での設定に合わせたDBになっています。
[サンプルアプリケーション側で必要なテーブルのcreate文](https://github.com/gyarasu/mysql57-docker/blob/master/myapp/initdb.d/create-sample-table.sql)が起動時に実行され、テーブルが作成されるようになっています。

### 始め方
起動方法はとても簡単です。それぞれのリポジトリを引っ張ってきて、下記を実行します。
①Dockerコンテナの起動

```shell
$ docker-compose up -d
```

②アプリケーションの起動

```shell
$ npm install
$ npm run dev
```

### PM2
ローカルで開発するにあたっては上記で問題ありません。
このテンプレートには[PM2](http://pm2.keymetrics.io/)の設定ファイルも含まれていて、実稼働環境でクラスタモードで動かせるようになっています。

- クラスタ起動
- 80番ポートの使用
- クラスタモード時のロギング

Nodeサーバにおいては上記のような課題が出てくるのですが、それについては[NuxtMeetupの発表資料](https://speakerdeck.com/gyarasu/hurontoendoenzinia-shi-jia-dong-made-hitoridedekirumon?slide=19)をご参照ください。
PM2を使ってシンプルに対応できます。


```yaml:pm2.config.yml
apps:
  - script: ./server/index.js
    name: 'myapp'
    exec_mode: 'cluster'
    instances: 0
    log_date_format: 'YYYY-MM-DD HH:mm Z'
    instance_var: 'MYAPP'
    env_production:
      PORT: 3000
      NODE_ENV: production
```

- `script`: Nodeサーバの起動スクリプトファイル
- `name`: PM2で使うアプリケーション名
- `exec_mode`: 実行モード
- `instances`: クラスタモード実行時のインスタンス数（0=マシンコア数で起動）
- `instance_var`: log4js×pm2-intercomでクラスタモードロギングする際にconfigに設定する値
- `env_xxxx`: 起動モードごとの環境変数設定


PM2のによるアプリケーションの起動方法は次のような感じです。
`--env`で環境を指定することで、その環境に対応する環境変数が設定されます。

```bash
$ pm2 start pm2.config.yml --env production
```

## まとめ
今回ご紹介したテンプレートは、新規サービスのプロトタイピング（β版くらいまで？）や小規模アプリケーション開発の素早い開発には役に立つのではないかと思います。

小規模であればサーバレスにしてバックエンドはFirebaseを使うといったような選択肢ももちろんあります。
今回は、会社や組織の方針などによって、新しい環境が用意できなかったり、承認を得るのに労力が必要であるような状況を考慮して、Webサーバ+DBサーバ（AWSでいうと、EC2+RDS）という、どこでも成立しそうなオーソドックスな環境を想定してみました。


餅は餅屋という言葉がある通り、それぞれ異なる得意分野を持つ人が集まって作ったほうがもちろん良いのですが、フロントエンドエンジニアとしてレイヤーに縛られない知識や経験があることは組織全体をエンパワーメントするエネルギー源になる可能性があると思います。
フロントエンドエンジニアの+αの価値を作っていく一助となれば幸いです。