Vue.jsで遊んでみた　【STEP 0】Node.jsでサーバーの構築

ちょっと周りでVue.jsが流行って来てるので、持ってる知識のアウトプット及び新たな知識のインプットを行うべく記事を書くことに。
Vue.jsを触るのはかれこれ一年ぶりなので一から学ぶつもりで一つ一つ進めていこうかと思います。

## 準備
Vue.jsの勉強だけなら正直ブラウザ一つで頑張ればなんとかなる。が、APIとか叩きたいしその内容も自分で管理したいし、何より簡単にブラウザに変更を反映したい。
ということでVue.jsに入る前にローカルで勉強用のサーバーを作ってみようと思いました。

### 使用ツール
- Node.js(v10)

今回はNode.jsのexpressを使ってサーバーを構築したいと思います。Node.jsの採用理由は~~僕がこれしか使えないから~~Vue.jsと同じJavaScriptで書けるからです。

### 参考サイト
[Express 4.x APIリファレンス](https://expressjs.com/ja/4x/api.html#express)
[ゼロからはじめるExpress + Node.jsを使ったアプリ開発](https://qiita.com/nkjm/items/723990c518acfee6e473)

## サーバー構築
### 構成
今回サーバーを構築するにあたり、以下のようなディレクトリ構成を作りました。

~~~
localserver
 |-index.js
 |-public
   |-index.html
   |-test.html
~~~

### expressのインストール
`express`を使うために以下のコマンドをlocalserverディレクトリで実行します

~~~
npm install express
~~~

これでlocalserverディレクトリ配下にnode_modulesというディレクトリができまして、`express`が使えるようになります。

### 各ファイルの実装
次に各ファイルを実装します。とりあえずhtmlファイルは適当でいいので次のようにしました。

~~~html:index.html
<html>
<body>
    <h1>Index!!</h1>
</body>
</html>
~~~

~~~html:test.html
<html>
<body>
    <h1>Test!!</h1>
</body>
</html>
~~~

そしてindex.jsですが、以下のようにしました

~~~js:index.js
const express = require("express")
const app = express()

app.use(express.static('public'))

app.listen(3000,()=>{
  console.log("server start")
})
~~~

最初の2行で`express`のアプリケーションを作ってます。

次の`app.use`は指定されたパスで始まるリクエストが来たらここを参照しろよって指定してます。リクエストのパスが`"/"`だけだとデフォルトで`index.html`を参照します。

最後の`app.listen`は指定したポートとホストと接続させる部分です。リファレンスによると

>This method is identical to Node’s http.Server.listen().

つまりNodeの`http.Server.listen`を使ってるらしいです。
今回は適当に3000番ポートを指定してホストは指定しませんでした。
またコールバックも特に必要ないのですが、コマンドを実行した時にちゃんとうまくいったか分かりにくいので、`"server start"`をコンソールに表示させるようにしました。

### サーバーの立ち上げ
以上で準備が整ったのであとはlocalserverディレクトリで以下のコマンドを実行すればサーバーが立ち上がります。

~~~
node index.js
~~~

`"server start"`とコンソールに出てきたら成功です。ブラウザを立ち上げてurlに`localhost:3000/`を指定してアクセスしてみてください。
Index!!と表示されていますか？
続いて`localhost:3000/test.html`にアクセスしてみてください。表示が変わっているはずです。
またそのまま`test.html`ファイルを適当に編集して変更を保存した後、そのままブラウザをリロードしてみてください。サーバーをリスタートかけなくても画面が変更されます。
サーバー止めるときはctrl+Cとかで中止するとファイルの実行が止まります。`index.js`等jsファイルの変更を反映させるときはこの方法でサーバーを止めて再度`node index.js`を実行します。

### これで十分だけど
　ここまでで十分Vue.jsを扱う環境が出そろったのですが、何となく`/test.html`ってするのださい気がする、てかいちいち`.html`って指定するのめんどくさい、`/test`で指定できるようにしたい...
ということで`index.js`に次の文を追加しました。

~~~js:index.js
app.use('/test',express.static('public/test.html'))
~~~

これでちゃんと`localhost:3000/test`で`test.html`を参照させることができるのですが、いや、htmlファイル追加するたびにjsを更新するの余計めんどくさいやん。別に外部に公開するわけじゃないし、セキュリティ度外視で極力サーバーの方を気にせずhtml増やしたり減らしたりしたい...

### 解決方法
 リファレンスを参照しながら試行錯誤したところ、以下の文を追加すればよさげでした。

~~~js:index.js
app.use('/:file',(req,res)=>{
  let fileName = `${__dirname}/public/${req.params.file}.html`
  res.sendFile(fileName,(err)=>{
    if(err) {
      console.log(err)
      res.sendFile(`${__dirname}/public/index.html`)
    }
  })
})
~~~

`app.use`の第一引数の`'/html/:file'`について。`/:file`のようにパス指定で`:`を用いるとコールバック関数で引数にとっている`req`の`params`から指定された部分の文字列を取得できます。
例えば`/html/hogehoge`というパスが指定されたら、`req.params.file`に`hogehoge`という文字列が入ってます。

その文字列を用いて指定のファイル名を作成し、`res.sendFile`で該当ファイルを返答します。ここでファイル名はルートから指定する必要があるので、index.jsがあるディレクトリパスが取れる`__dirname`を用いてファイル名を作成します。
該当するファイルがなかったときはエラーになるので、その時は取り合えずindex.htmlを返すようにしました。

これで`.html`という文字列を打つ必要がなくなり、かつ急遽htmlファイルを新たに追加するしてもコマンドをたたき直すことなくブラウザから参照できるようになりました。

## まとめ
　これで準備が整いました。これからhtmlファイルを編集しながらVue.jsのお勉強をしていきます。
　つたない内容でしたが最後までありがとうございました。