Vercel に既存の Express アプリをデプロイしたいとき、通常の app.listen()
を使うと上手く動かないことがあります。本記事では Vercel のサーバーレス環境に合わせた Express の書き方 をまとめます。
1. 問題
ローカル開発用に書かれた Express アプリ:
PORTは.envファイルに記載しています.
import express from "express";
const app = express();
app.get("/api/hello", (req, res) => {
res.json({ message: "Hello World" });
});
// ローカル用にサーバー起動
app.listen(process.env.PORT, () => {
console.log(`Server running on port ${process.env.PORT}`);
});
❌ 問題点
vercel は自分で HTTP サーバーhttp.createServer(app)
を立ち上げてリクエストを渡します。
そのため,自分でサーバーを立てる(listen)する必要がない
解決策
if (process.env.NODE_ENV !== "production") {
app.listen(3000, () => {
console.log("Local server running on http://localhost:3000");
});
}
export default app;
💡ポイント
ローカル(process.env.NODE_ENV="development")ではlistenしてブラウザで確認可能
デプロイ先(process.env.NODE_ENV="production")では,listenせずappをエクスポート
補足:自分のディレクトリ構成例
my-project/
├─ api/
│ └─ index.js ← Express アプリをまとめる
├─ package.json
api/index.js に Express をまとめてexport default app
するスタイル
Vercel の API Routes は 1 ファイル = 1 関数が基本だが、Express をまとめる方法も可能
だけど,ファイルごとにエンドポイントを作るべき?
まとめ
- Vercel は Serverless Function 環境なので app.listen() は不要
- Express アプリをそのまま動かすなら export default app
- 小さい API を増やす場合はファイルごとに関数を作る「純正 API Routes」スタイルも検討