🌟

Nuxt3でKoa.jsを使う

2023/07/02に公開

はじめに

Nuxt3には公式ドキュメントにある通り、Nitroというサーバエンジンが組み込まれており、わざわざexpress.jsやkoa.jsと組み合わせる必要はほぼありません。

この記事は、Nuxt2のサーバサイドでkoa.jsを使用していたプロジェクトを、大きな変更を加えずにNuxt3に移行することを目的としています。
もしNuxt3に移行するための時間が十分に取れるならば、koa.jsを捨てて公式にある書き直した方が将来的には良いかもしれません。最近の状況を見るに、移行の時間があるならNuxt自体をやめてNextにするという方も多い気がしますが...

動作環境

  • Node.js: 18.16.1
  • Nuxt: 3.5.3
  • Koa.js: 2.14.2

手順

nuxt.config.ts

Nuxtルートのserverというディレクトリの中にkoaのエントリーポイントとなるファイルを置いてしまうとNuxt3の通常のNitroで公開されるAPIのファイルと混合してしまうので、今回の記事ではserver-koaのディレクトリにkoa関連のファイルを置かれていると仮定します。

nuxt.config.ts
import "nuxt"

export default defineNuxtConfig({
  serverHandlers: [
    { route: "/api/v1/**", handler: "~~/src/server-koa/index.ts" },
  ],
})

他にも同じことをしている方のこの記事を参考にしていますが、以前のNuxtのserverMiddlewareの記述とは違い、serverMiddlewareではなくserverHandlersとなっていることに注意してください。pathではなくrouteというpropertyになっており書き方も**が必要であったりと、異なっていることにも注意です。

index.ts

ポイントはfromNodeMiddlewareでcallbackを囲うこと

src/server-koa/index.ts
import Koa from 'koa'
import Router from 'koa-router'

const app = new Koa()
const router = new Router()

router.get('/api/v1/hello', (ctx) => {
    ctx.body = "Hello World!"
})

app.use(router.routes()).use(router.allowedMethods());

export default fromNodeMiddleware(app.callback());

動かなかったところ

koa-sessionkoa-bodyparseなど使っている箇所は問題なく動いたのですが、koa-sendを使用して、ファイル配信を行うAPIがNitroの内部で動いているh3のエラーにより動きませんでした。
そのため、ファイル配信の部分だけ、sendStreamに書き換えることにしました。
結構使われそうな機能なのですが、Nuxt3.5の時点で今だにExperimentalなのは不安がありますね。

src/server/file.ts

import fs from "fs";
import path from "path";
import { defineEventHandler, sendStream } from "h3"

export default defineEventHandler((event) => {
  const filePath = path.join("path", "to", "sample.jpg")
  return sendStream(event, fs.createReadStream(filePath))
})

このようなこともあり、やっぱり新しくNuxt3でプロジェクトを作るのに、Koaを組み合わせることは、特に理由もない限りおすすめしません。

参考記事

ちょっと古いversionのNuxtで動かしている方の記事

https://qiita.com/msquare33/items/96abec0f2cf0d95dcda7

expressの場合

https://debug-life.net/entry/4263

Discussion