Vue-CLI-Plugin-Express を使って Vue + Express スタックを実現する
Vue.js でアプリを作りつつ、同時にバックエンド API も作りたいな、と思うと、Nuxt.js を使って実装しちゃう方法がすぐ思いつくかもしれない。
しかし、
- Vue CLI を使いたい
- API 側はそこまで大仰じゃなくて良い
という時に、Nuxt.js だと縛りが強くなってしまって若干使いづらい。
そこで見つけたのが、Vue-CLI-Plugin-Express という Vue CLI 用のプラグイン。既存の Vue CLI ベースのプロジェクトに、Express サーバを統合してくれるというモノだ。早速使ってみよう。
目次
- Vue CLI でプロジェクトを作る
- Vue-CLI-Plugin-Express をインストールする
- 試しにライブリロード開発してみる
- 本番ビルドの流れ
- Express サーバを TypeScript で実装したい
- 以上
Vue CLI でプロジェクトを作る
まずは Vue CLI を使ってプロジェクトを作る。@vue/cli
のバージョンは v4.4.4 を使用。
$ vue create practice-vue-express
TypeScript ベースで実装するため、「Manually Select Features」を選択し、Babel・TypeScript・CSS Pre-processors を有効にする。「Linter / Formatter」や「UnitTesting」、「Router」「Vuex」などはお好みで。
雛形ができたら、
$ cd practice-vue-express/
$ npm run serve
で http://localhost:8008/
に簡易サーバが立ち上がることを確認しよう。
Vue-CLI-Plugin-Express をインストールする
雛形プロジェクトの動作確認ができたら、プラグインをインストールする。
$ vue add express
# 以下2つの質問に答える
? Should serve vue app? Yes
? Where will be located your server? ./srv
🚀 Invoking generator for vue-cli-plugin-express...
✔ Successfully invoked generator for plugin: vue-cli-plugin-express
インストールコマンドを叩くと2つの質問が問われる。「Should serve vue app?」は Yes と答え、「Where will be located your server?」はデフォルトの ./srv
のまま答える。
このようにすると、
package.json
にexpress
とexpress:run
という npm-scripts が追記されるvue.config.js
に上2つの質問の内容が書き込まれる./srv/index.js
が生成される
といった変化が出る。
試しにライブリロード開発してみる
./srv/index.js
を見ると、export default
に囲まれているものの、何やら Express でお馴染みの app
変数が用意されているようだ。コメントアウトでサンプルコードも書かれているので、試しに次のようにアンコメントしてみよう。
srv/index.js
import express from 'express';
// import socketIO from "socket.io";
export default (app, http) => {
// ↓ ココからアンコメント
app.use(express.json());
app.get('/foo', (req, res) => {
res.json({msg: 'foo'});
});
// ↑ ココまでアンコメント
//
// app.post('/bar', (req, res) => {
// res.json(req.body);
// });
//
// optional support for socket.io
//
// let io = socketIO(http);
// io.on("connection", client => {
// client.on("message", function(data) {
// // do something
// });
// client.emit("message", "Welcome");
// });
}
このようにしたら、
$ npm run express
を叩いてみる。すると http://localhost:3000/
に簡易サーバが起動する。先程 /foo
というパスのルーティングをアンコメントで実装したので、
http://localhost:3000/foo
にアクセスすると、{"msg":"foo"}
というレスポンスが得られる。./srv/index.js
の実装のとおりだ。
さて、ココで、$ npm run express
を実行したターミナルウィンドウはそのままに、別タブで
$ npm run serve
を実行してみよう。コチラは元々の Vue CLI が提供する、フロントエンド環境の簡易サーバが立ち上がる。ポート番号は先程の 3000 番ではなく 8080 版で立ち上がっていることに留意。
http://localhost:8080/
にアクセスすれば Vue アプリの画面が開くのはそのとおりだが、ココで
http://localhost:8080/foo
にアクセスしてみよう。すると、フロントエンド側の 8080 ポートであるにも関わらず、バックエンド側の /foo
の情報がレスポンスされる。8080 ポートの簡易サーバがプロキシの役割を果たして、バックエンド側の簡易サーバにアクセスしているのだ。
つまり、Vue アプリ内では、オリジンを指定せず /foo
への Ajax 通信処理を実装すれば、2つの簡易サーバを立ち上げてそれぞれでライブリロード開発ができるワケである。
プラグインの説明では、コレを「Fallback」と表現している。
本番ビルドの流れ
プラグインが簡単にバックエンドを用意してくれて、Vue アプリと同一サーバで動いているかのようなフォールバック機能も提供してくれることは分かった。
では、本番ビルドはどのように行うかというと、まず
$ npm run build
でフロントエンド側のコードを ./dist/
にビルドして配置しておく。
そしたら
$ npm run express:run
で Production 用の Express サーバを起動する。コチラのコマンドはライブリロードは行わない他、./dist/
配下の資材を参照するので、8080
ポートで何が動いていようと無視される。使用するポートは $ npm run express
の時と同じ 3000 番ポートなので、
http://localhost:3000/
にアクセスすれば Vue アプリが見えるし、
http://localhost:3000/foo
にアクセスすれば Express で定義したルーティングに基づき JSON が返されるという具合だ。
Express サーバを TypeScript で実装したい
さて、コレでひとまずプラグインの動作は確認できたが、Express サーバのコードは ./srv/index.js
ということで、JavaScript 形式になっている。コレを TypeScript で実装したい場合はどうしたらいいかというと、単純に拡張子を .ts
に変えるだけで良い。
./srv/index.ts
(拡張子を変更)
試しにコード中に TypeScript 記法を混ぜ込んで、動作を確認しよう。
app.get('/foo', (req, res) => {
const fooMessage: string = 'foo';
res.json({ msg: fooMessage });
});
こんな感じ。
VSCode 上での補完などを効かせるには、tsconfig.json
を開き、include:
の配列の中に
"srv/**/*.ts"
を追加してやれば良いだろう。
コレで実際に動かしてみると、ちゃんと TypeScript と解釈して動作していることが分かる。
# どちらも動く
$ npm run express
$ npm run express:run
内部的には ts-node
を使って動いているのかな?
以上
ベースとなる Vue CLI アプリに、軽く Express サーバを立てて API を組み合わせたくなった時に丁度良いプラグインであろう。