prisma/adapter-d1はフレームワークと組み合わせて使えるのか?
Wasmバイナリを含むバンドルサイズについて
@prisma/adapter-d1はネイティブコードだったlibquery_engineがWasmバイナリになっています
Cloudflare Workersはup to 1 MB on the Workers Free planの制限があるので、Wasmバイナリがどの程度のサイズを占めているのかが気になり調べました
raw codeに近づけるためにJavaScriptでPrismaClientを呼び出す最小のWorkerを作ってみます
import { PrismaClient } from '@prisma/client'
import { PrismaD1 } from '@prisma/adapter-d1'
export default {
async fetch(request, env, ctx) {
const adapter = new PrismaD1(env.MY_DATABASE)
const prisma = new PrismaClient({ adapter })
const usersCount = await prisma.user.count()
return new Response(`There are ${usersCount} users in the database`)
},
}
❯ npx wrangler deploy --outdir bundled/ --dry-run
--dry-run: exiting now.
Total Upload: 2181.44 KiB / gzip: 815.33 KiB
gzip: 815.33 KiB
になりました。gzip圧縮されたサイズで最大1MB制限であることはドキュメントに書かれていますので、8割ぐらいはPrisma Clientが占めるのだなと分かります
以下が内訳です
❯ du -sh bundled/
3.0M bundled/
❯ tree bundled
bundled
├── 5343c5664d9b411cd10438666dc2381e8c450cda-query_engine_bg.wasm
├── README.md
├── index.js
└── index.js.map
❯ du -sh bundled/*
2.5M bundled/5343c5664d9b411cd10438666dc2381e8c450cda-query_engine_bg.wasm
4.0K bundled/README.md
208K bundled/index.js
328K bundled/index.js.map
これをgzip圧縮してみると同サイズになりました
❯ find bundled -type f \( -name "*.js" -o -name "*.wasm" \) -print0 | tar -czvf bundled.tar.gz --null -T -
a bundled/5343c5664d9b411cd10438666dc2381e8c450cda-query_engine_bg.wasm
a bundled/index.js
❯ du -sh bundled.tar.gz
816K bundled.tar.gz
なので、1000k-816K=184kbが開発者が使えるバンドルサイズになります
Next.js
Next.jsは@cloudflare/next-on-pagesでWorkers形式にビルドします
以下のコードを用意しました
import { getRequestContext } from '@cloudflare/next-on-pages'
import { PrismaClient } from '@prisma/client'
import { PrismaD1 } from '@prisma/adapter-d1'
export const runtime = 'edge'
export default async function Home() {
const adapter = new PrismaD1(getRequestContext().env.MY_DATABASE)
const prisma = new PrismaClient({ adapter })
const todos = await prisma.todo.findMany()
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
<pre>
{JSON.stringify(todos, null, 2)}
</pre>
</div>
</main>
);
}
❯ npx next build
❯ npx @cloudflare/next-on-pages
❯ find .vercel/output/static/_worker.js -type f \( -name "*.js" -o -name "*.wasm" \) -print0 | tar -czvf bundled.tar.gz --null -T -
a .vercel/output/static/_worker.js/index.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/cache/cache-api.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/cache/kv.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/cache/adaptor.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/manifest/27d10e462fba646daaa29468a0656e12.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/manifest/__RSC_SERVER_MANIFEST.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/wasm/wasm_5343c5664d9b411cd10438666dc2381e8c450cda.wasm
a .vercel/output/static/_worker.js/__next-on-pages-dist__/webpack/44bff480f105853cb03b9b061f5738d6.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/webpack/8090d4b5871bbe46edd85a7368aa285a.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/functions/_not-found.func.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/functions/index.func.js
a .vercel/output/static/_worker.js/__next-on-pages-dist__/functions/api/hello.func.js
❯ du -sh bundled.tar.gz
1.0M bundled.tar.gz
ギリだ……
試しにデプロイしてみるも、デプロイコマンド自体は成功するも、Status: Failed
の結果になり、反映が完了しません
Hono(React SPA)
HonoでAPI付き雑React SPA最小でyusukebeさんが解説されている構成ですが、これは余裕でいけました(Workers側にSPAのSSRを含めてないのでそれはそう)
❯ npx wrangler deploy --compatibility-flag nodejs_compat --dry-run --outdir bundled dist/_worker.js
-dry-run: exiting now.
Total Upload: 2275.50 KiB / gzip: 837.49 KiB
❯ find ./bundled -type f \( -name "*js" -o -name "*.wasm" \) -print0 | tar -czvf bundled.tar.gz --null -T -
a ./bundled/5343c5664d9b411cd10438666dc2381e8c450cda-query_engine_bg.wasm
a ./bundled/_worker.js
❯ du -sh bundled.tar.gz
840K bundled.tar.gz
D1への読み書きを含めたデモ: https://prisma-d1.pages.dev/
ソースコード: https://gist.github.com/laiso/fe4ddd71f3f041db47daddc35b31c5c2
Remix
Prisma driver adapter for Cloudflare D1をRemixに組み込むによるとnext-on-pagesと同じくデプロイしても動作しない状態になるようです
有料版では動作するのでサイズの問題で刺さっているのでは? という予測ができますね
NuxtやSvelteKitは?
当方未確認なのでご存知の方は教えてください
Discussion