この記事をみて、Nitro サーバに興味が出たので、
ドキュメントみながら、少し触ってみたときの備忘録(*´ω`*)
全てを
devDependencies
にするよ。具体的には、ビルド後の資材が必要最低限のもので.output
ディレクトリにまとめられるから、 「巨大な node_modules を AWS Lambda にあげて、コールドスタート時のあまりの遅さに悩まされる」 なんて事態を回避できるよ。
ビルドも早く軽量で、よさそうな感じ(*´ω`*)
Nuxt3がなんであの書き方になったのかも少し理解できた気がする。
install
package.jsonの設定
$ pnpm dlx giget@latest nitro nitro-app
初期設定で作成されるけど、少し変更したのがこれ。
{ "scripts": { "dev": "nitropack dev", "build": "nitropack build", "preview": "node .output/server/index.mjs", "postinstall": "nitropack prepare" }, "packageManager": "pnpm@8.3.1", "engines": { "pnpm": ">=8", "node": ">=18" }, "devDependencies": { "nitropack": "^2.5.2" } }
auto importsを使っているので、prepare
かdev
を実行しないと、
型が生成されないので、postinstall
に設定しておく。
npmrcの設定
そのまま、pnpm install
すると、いくつか依存先の型定義が見つからないので、
shamefully-hoist=true
を設定しておく。
# .npmrc shamefully-hoist=true
install
あとは、インストールなどすればOK
$ pnpm install $ pnpm dev $ pnpm build && pnpm preview
Routing
ファイルパスがそのままルートになるよう。
# デフォルト api/ test.ts <-- /api/test routes/ hello.ts <-- /hello nitro.config.ts
ただ、api/
ディレクトリの仕様が、
Vercelの仕様と競合するので、Nuxt3のように
# Nuxt3 routes/ api/ test.ts <-- /api/test hello.ts <-- /hello nitro.config.ts
という形がよいぽい。
特定のメソッドのみの場合は、こんな感じのファイル名にすればOK
- GET:
routes/users/[id].get.ts
POST:
routes/users.post.ts
Request/Response
シンプルなのはこの形。
パスパラメタはevent.context.params
から取得。
// routes/hello/[name].ts export default eventHandler(event => {nitro : `Hello ${event.context.params.name}!` } );
内部では、h3というhttp frameworkを使っているので、
queryやheaderの取得、response関係の設定はこっちを見るといい。
// routes/[...params].ts export default eventHandler((event) => { const pathParams = event.context.params; const query = getQuery(event); const header = getHeaders(event); const sessions = event.context.sessions; const cookie = getCookie(event, "cookie_key"); const method = getMethod(event); setResponseStatus(event, 404); return { nitro: "Is Awesome!", pathParams: pathParams, query, header, method: method || "(none)", cookie: cookie || "(none)", sessions: sessions || "(none)", }; });
// "http://localhost:3000/a/b/?p=1&a=1&a=2"の場合 { "nitro": "Is Awesome!", "pathParams": { "params": "a/b" }, "query": { "p": "1", "a": [ "1", "2" ] }, "header": { "cookie": "cookie_key=something; cookie_key2=anything", // ... }, "method": "GET", "cookie": "local", "sessions": "(none)" }
全部のパスを取得したい場合はこれ。
// routes/[...].ts export default eventHandler(event => `Default page`)
Cache/Storage
Cache-Control
ヘッダーなど、Cacheを使いたい場合、
cachedEventHandler
に変えると、オプションで設定できる。
// routes/[...params].ts export default cachedEventHandler( (event) => ({ seconds: new Date().getSeconds() }), { swr: false, maxAge: 5 } );
ルートを正規表現などで指定することもできるけど、
現段階で、experimental
(実験的)な機能。
// nitro.config.ts import { defineNitroConfig } from "nitropack/config"; export default defineNitroConfig({ routeRules: { "/blog/**": { swr: 60 * 60, // or cache: { maxAge: 60 * 60 } }, }, });
- develop modeだと、ファイル(FS driver)(
.nitro/cache
) - production modeだと、メモリ上(memory driver)
を利用する。が、Radisなどにも変更ができる。
import { defineNitroConfig } from "nitropack/config"; export default defineNitroConfig({ storage: { cache: { driver: "redis", url: "redis://localhost:6379", }, } });
いずれもUnstorageのdriverを利用。
DBアクセスなどもそのあたりの設定を使えるよう。
Resources
Resources系は2種類あり
public/
... 配置されるファイルaseets/
... ビルド時にバンドルされるファイル
という形。
public/ image.png <-- /image.png video.mp4 <-- /video.mp4 robots.txt <-- /robots.txt assets/ my_file <-- useStorage('assets:server').getItem("my_file") package.json nitro.config.ts
assets/
ディレクトリにあるファイルは、Unstorage
経由で扱える。
Middleware
Middlewareについてドキュメントには詳しく書いてないけど、
middleware/
配下に配置するよう。
ファイル名順に実行されるので、順番をファイル名の先頭に付けておくとよい。
middleware/ ├── 1.common.ts └── 2.auth.ts
Middlewareの中身は、routingと同じ。
認証チェックのサンプルより。
// middleware/2.auth.ts export default defineEventHandler((event) => { event.context.auth = { name: "User " + Math.round(Math.random() * 100) }; });
event.context
は、h3のH3EventContext
なので、
そちらの型を拡張すればよいっぽい。
declare module "h3" { interface H3EventContext { auth: { name: string } } } export {};
Plugins
plugins/
配下に配置すると、auto importしてくれる。
plugins/ 1.first.ts 2.second.ts
// plugins/test.ts export default defineNitroPlugin((nitroApp) => { console.log('Nitro plugin', nitroApp) })
Deploy
デプロイ先の設定をまとめたプレセットが用意されているので、
それらを利用すればOK。
# Node.js Server(default) $ nitro build # Firebase Hosting $ NITRO_PRESET=firebase nitro build # AWS Lambda $ NITRO_PRESET=aws-lambda nitro build # Heroku $ NITRO_PRESET=heroku nitro build # Vercel $ NITRO_PRESET=vercel nitro build # GitHub Pages $ NITRO_PRESET=github-pages nitro build
ほか、Netlify、Azure、Denoなども用意。
各設定値のソースはこのあたり。
AppConfig/RuntimeConfig
Nuxt3と同様、useAppConfig(event?)
、useRuntimeConfig(event?)
が使える。
Environment Variables
NITRO_PRESET
以外にも、NITRO_PORT
やNITRO_HOST
などもある。
このあたりは、unenvを利用しているよう。
実験的な機能
nitro.config.ts
でフラグを立てると、
実験的な機能を使うことができる。
// nitro.config.ts import { defineNitroConfig } from "nitropack/config"; export default defineNitroConfig({ experimental: { openAPI: true, wasm: true, }, });
- openAPI
/_nitro/swagger
と/_nitro/openapi.json
エンドポイントを自動生成- Swagger UIを自動生成してくれるので、APIを叩きやすい
- ただ、パスパラメタの解析までなので、今後を期待
- wasm
- Enable WASM support
- らしい。。
以上!! 触った感じ、ビルドも実行も早くていい。
Nuxt3の理解も深まった気がする(*´ω`*)