カテゴリー
ViteでDevサーバーのProxyオプションを高度に操作する方法
※ 当ページには【広告/PR】を含む場合があります。
2024/12/26

前回はViteのProxyサーバー設定から、基礎的なDevサーバーへのCORS対策を説明していました。
そちらの記事では、
rewrite
target
今回は、
rewrite
ProxyOptionsを使いこなす
ViteのProxyオプションの実装は以下のリンク先のコードで確認できます。
この中では、いくつかの関数型が
HttpProxy.ServerOptions
ちなみに大本のプロキシサーバーのオプションに関しては、拡張元の
//...
export interface ProxyOptions extends HttpProxy.ServerOptions {
/**
* rewrite path
*/
rewrite?: (path: string) => string
/**
* configure the proxy server (e.g. listen to events)
*/
configure?: (proxy: HttpProxy.Server, options: ProxyOptions) => void
/**
* webpack-dev-server style bypass function
*/
bypass?: (
req: http.IncomingMessage,
/** undefined for WebSocket upgrade requests */
res: http.ServerResponse | undefined,
options: ProxyOptions,
) => void | null | undefined | false | string
/**
* rewrite the Origin header of a WebSocket request to match the target
*
* **Exercise caution as rewriting the Origin can leave the proxying open to [CSRF attacks](https://owasp.org/www-community/attacks/csrf).**
*/
rewriteWsOrigin?: boolean | undefined
}
さて、
rewrite
configure
bypass
場合によっては開発環境で高度なhostの書き換えや、リクエスト/レスポンスの処理などを挟みたいことがあります。
configure
bypass
configure
bypass
configureメソッド
configure
最初の引数にて、プロキシサーバーインスタンス、2つ目の引数でそのプロキシオプションがそれぞれ参照されています。
例えばサーバーにエラーハンドリングを独自に挟みたいときなど、この
configure
//...
// Listen for the `error` event on `proxy`.
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong. And we are reporting a custom error message.');
});
// Listen for the `proxyRes` event on `proxy`.
proxy.on('proxyRes', function (proxyRes, req, res) {
console.log('RAW Response from the target', JSON.stringify(proxyRes.headers, true, 2));
});
// Listen for the `open` event on `proxy`.
proxy.on('open', function (proxySocket) {
// listen for messages coming FROM the target here
proxySocket.on('data', hybiParseAndLogMessage);
});
// Listen for the `close` event on `proxy`.
proxy.on('close', function (res, socket, head) {
// view disconnected websocket connections
console.log('Client disconnected');
});
のように利用できます。
Vite側への実装の一例として、
import { defineConfig } from 'vite';
//...
export default defineConfig({
//...
server: {
proxy: {
'^/s3/.*': {
changeOrigin: true,
configure: (proxy, options) => {
//👇プロキシサーバーへイベントリスナー追加
proxy.on('proxyRes', (proxyRes, req, res) => {
console.log('RAW Response from the target:', JSON.stringify(proxyRes.headers));
});
//👇rewriteメソッドを再定義
options.rewrite = (path) => {
const _match = path.match(/^\/s3\/(.+)\/(.+)\/.*/m);
let _region = '', _bucket = '';
if (_match) {
_region = _match[1]??'';
_bucket = _match[2]??'';
}
//👇アクセス先となるターゲット自体を書き換え
options.target = `https://${_bucket}.s3.${_region}.amazonaws.com`;
return path.replace(`/s3/${_region}/${_bucket}`, '')
}
}
}
}
},
//...
})
というように書き換えることで、例えばDevサーバーの
/s3/hoge-piyo/us-east-1
https://hoge-piyo.s3.us-east-1.amazonaws.com
proxyRes
bypassメソッド
もう一つ
bypass
このメソッドは外部へのリクエスト、もしくは外部からのレスポンスに対して何らかの操作を行いたい場合に利用します。
例えばホスト名ならびに特定のHTTPヘッダーも書き換えたい場合、
import { defineConfig } from 'vite';
//...
export default defineConfig({
//...
server: {
proxy: {
'^/s3/.*': {
changeOrigin: true,
bypass: (req, res, proxyOptions) => {
const _match = req.url.match(/^\/s3\/(.+)\/(.+)\/.*/m);
let _region = '', _bucket = '';
if (_match) {
_region = _match[1]??'';
_bucket = _match[2]??'';
}
proxyOptions.target = req.headers['host'] = `https://${_bucket}.s3.${_region}.amazonaws.com`;
req.headers['date'] = (new Date()).toUTCString();
}
}
}
},
//...
})
とすると、Devサーバーの
/s3/hoge-piyo/us-east-1
target
Host
Date
まとめ
今回もViteのProxyサーバーのオプションについてちょっとだけ深堀した内容を説明してきました。
この辺はDevサーバーの話なので、プロダクトでの挙動とは直接関係しないものの、Viteによる快適な開発環境を整えるためにはしっかり理解しておきたいポイントになっています。
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー