AstroのNode.jsアダプタを使って、基本的にサーバーで動作するサイトを作るとする。
このとき、astro.config.js
でoutput: "server"
を指定しつつも、Aboutページのような静的なページは、export const prerender = true
することもできる。
ただこのprerenderされたページって、そういえばどうやってレスポンスされるんやっけ?
既に静的に生成されてるなら、Nodeまでリクエストを到達させなくてもよくない?CDNで静的アセットとして存在しなかったリクエストだけ、Nodeに任せたいかもなって。
そんなとき、どうやるのか。
そもそも
そういう用途のために、このアダプターにはmode
というオプションがあった。
export default defineConfig({
output: "server",
adapter: node({
mode: "middleware", // or `"standalone"`
}),
});
このmode
を見て、ビルド時のエントリーポイントの中身が変わる仕掛け。
middleware
モード
このモードでは、Expressや既成のフレームワークのMiddlewareとして動く。
fn(req, res, next, locals)
というI/Oを想定してた。
動的な部分のみが対象となるので、静的に生成したものに関しては、何もしてくれない。
上物の実装側で、./dist/client
配下に生成されたものを、自分でサーブしないといけない。
standalone
モード
こっちのモードでビルドすると、node ./dist/server/entry.mjs
でそのままサーバーが起動するコードになる。
中身はExpressとかではなく、node:http(s)
で書かれた素直な実装になってた。
middleware
モードとは違って、静的ファイルも対象にしてくれてる。
node:fs
でファイルを見つけて、それをsend
を使ってStreamingで返してるだけ。
pillarjs/send: Streaming static file server with Range and conditional-GET support https://github.com/pillarjs/send
./dist/client
配下に生成されるファイルはハッシュを含むファイル名になってるので、アグレッシブにキャッシュさせる設定にしてあるとのこと。
Cache-Control: public, max-age=31536000, immutable
というわけで
どちらのモードにするにせよ、./dist/client
配下を自分で先に返すようにしちゃえばいい。
その裏がstandalone
かmiddleware
モードかは、お好きにどうぞという感じ。
@astrojs/node | Docs https://docs.astro.build/en/guides/integrations-guide/node/