追記: webpack-serve は非推奨になり、 webpack-dev-server の開発が再開しました。ここは webpack-dev-server を使っておきましょう。
とりあえず動かしたい場合は https://qiita.com/ma2saka/items/eb4190a009da9649583c に最低限の設定方法を書いたのでそちらを参照する。
webpack-serve は webpack で開発しながら動的にビルド走らせてサーバで動作確認するためのものと認識している。「ファイルを監視して webpack を適切に実行してブラウザをリロードする」が主な役割。
ただ「本番系では手前にリバースプロキシがいてURLの書き換えやってる」とか「APIサーバが別にいてそっちへのアクセスはモックしたい」とかいろいろ都合があるもので、そのあたりはアドオンとしてカスタマイズする流れになる。
アドオンは koa
のミドルウェアを追加することになる。 koa
は https://github.com/koajs/koa で開発されている、Node.js の軽量なWebアプリケーションフレームワークなのだけど、ここでは詳細には踏み込まない。
ただ、以下サンプルで示すコードで出てくる ctx
は Koa の Context オブジェクトなんだぜ、とか app.use(async (ctx, next) => {
あたりの記述はkoa公式のREADMEで紹介されている書き方に習っているので他の箇所とちょっと命名のノリが違うんだ、くらいで一つよろしくお願いいたします。
serve.config.js で addon を設定する
/hello ときたら {"hello":"world"}
を返す
options.add
に、 koa
のミドルウェアを設定する関数を渡すようにする。
const serve = require('webpack-serve');
const config = require('./webpack.config.js');
const argv = { }
const addon = (app, middleware, option) => {
middleware.webpack();
middleware.content();
app.use(async (ctx, next) => {
if(ctx.originalUrl.match(/\/hello/)){
ctx.response.status = 200
ctx.response.type = 'json'
ctx.response.body = JSON.stringify({hello: "world"})
}else{
await next()
}
});
}
serve(argv, { config, content: 'public/', port:8080, add: addon})
サーバを立ち上げ、curl でアクセスすると、ちゃんと
- Content-Type が
application/json
- HTTP Status Code が
200
- body が設定したJSONデータ
になっていることがわかる。
$ curl -i http://localhost:8080/hello
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 17
Date: Mon, 13 Aug 2018 01:35:58 GMT
Connection: keep-alive
{"hello":"world"}
簡単。
ここで以下のようにミドルウェアの内容を修正してみると、
app.use(async (ctx, next) => {
if(ctx.originalUrl.match(/\/hello/)){
console.log(ctx); // レスポンスを設定する前に ctx の中を確認する
ctx.response.status = 200
ctx.response.type = 'json'
ctx.response.body = JSON.stringify({hello: "world"})
}else{
await next()
}
});
レスポンスを返す前の段階で「リソースが見つからない」判定がなされ、404になっていることがわかる。
{ request:
{ method: 'GET',
url: '/hello',
header:
{ host: 'localhost:8080',
'user-agent': 'curl/7.54.0',
accept: '*/*' } },
response: { status: 404, message: 'Not Found', header: {} },
app: { subdomainOffset: 2, proxy: false, env: 'development' },
originalUrl: '/hello',
req: '<original node req>',
res: '<original node res>',
socket: '<original node socket>' }
404の内容をカスタマイズする
そこで、「静的コンテンツが見つからなかったら」JSONを返すように変更してみる。
app.use(async (ctx, next) => {
if(ctx.status === 404){
ctx.response.type = 'json'
ctx.response.body = JSON.stringify({not: "found"})
}else{
await next()
}
});
これで、
$ curl http://localhost:8080/
hello
$ curl http://localhost:8080/hoge
{"not":"found"}
404だった場合の結果ページを上書きすることができた。
まとめ
webpack-serve
に動的な処理をアドオンするのはとても簡単。使い所は、これから考える。