開発環境と本番環境の差異をなるべく抑えて、Cloudflare D1 の環境構築をしてみます
動作確認環境
Next.js 15.1.7
@opennextjs/cloudflare 0.5.0
Cloudflare D1 は SQLite ベースのデータベースです
もちろん Edge Runtime 上でも動作するので、バックエンドサーバ不要でデータベースを触れます
今回は、本番環境と開発環境を整えていこうと思います
D1 データベースが存在していることが前提になるので、事前に作成しておいてください
本番環境は、バインディングを利用し、環境変数からデータベースにアクセスします
Pages の Settings の Bindings 項から D1 database を選択し、環境変数名を設定することでアクセスできます
なお Preview と Production で個別に設定する必要があります

ここまで来ると、環境変数からアクセスすることができます
'use server'const db = process.env.DB
型が欲しい場合は env.d.ts に型を定義しておきます
import { D1Database } from '@cloudflare/workers-types'declare global {namespace NodeJS {interface ProcessEnv {DB: D1Database}}}
Cloudflare は CLI 用に wrangler という強力なツールを持っています
wrangler について
wrangler は、シェルから Cloudflare の本番環境にもアクセスでき、開発環境も用意されています
例えば、本番環境のデータを開発環境にコピーすることも容易です (逆もまた然り)
仕組みが少し複雑ですが wrangler は Miniflare というシミュレータを利用しています
wrangler のローカル環境への操作は Miniflare に記録されます
そして、Next.js など TypeScript から D1 にアクセスする場合は、Miniflare を利用することになります
なので、最初は Miniflare を直接利用することにしたのですが...
Error: The package "@cloudflare/workerd-darwin-arm64" could not be found, and is needed by workerd.If you are installing workerd with npm, make sure that you don't specify the"--no-optional" flag. The "optionalDependencies" package.json feature is usedby workerd to install the correct binary executable for your current platform.at (rsc)/./node_modules/miniflare/node_modules/workerd/lib/main.js (.next/server/vendor-chunks/miniflare.js:30:1)at __webpack_require__ (.next/server/webpack-runtime.js:33:43)at (rsc)/./node_modules/miniflare/dist/src/index.js (.next/server/vendor-chunks/miniflare.js:20:1)at __webpack_require__ (.next/server/webpack-runtime.js:33:43)at __webpack_require__.t (.next/server/webpack-runtime.js:76:38)at async getD1Session (src/components/utils/cloudflare/d1/getD1Session.ts:20:25)18 | console.log(c)19 |> 20 | const Miniflare = (await import('miniflare')).Miniflare| ^21 | const mf = new Miniflare({22 | modules: true,23 | liveReload: true,
なんかエラーになりました 🙃
どうやら workerd が見つからないようでした (node_modules には存在しているんですけどね...)
一応 Discussion を作って相談してみました
実は Miniflare は fs 等に依存しており Edge Runtime 上で動作しません
仮にこれで動いても面倒だなあと思っていたのですが、ここで OpneNext という救世主が
OpenNext について
OpenNext は Next.js の vercel 依存を解決することを目的としたプロジェクトのようです
Cloudflare へのビルドやデプロイもできるようなので、時間があればこれも試してみたいですね
Next.js の Edge Runtime から Miniflare にアクセスできるようなので、これをインストールしました
yarn add -D @opennextjs/cloudflareプロジェクトルートに wrangler.toml を作成します
binding は、先ほど Cloudflare で設定したものとは避けた方がいいです (デプロイ時に衝突してエラーになりました)
[[ d1_databases ]]binding = "__DB"database_name = "DB"database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"preview_database_id = "__DB"
database_id は UUID で、Cloudflare D1 のダッシュボード上で確認できます
wrangler にログインしていれば、以下のコマンドでも確認できます
yarn wrangler d1 list次に next.config.js に初期化コマンドを設置します
import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";initOpenNextCloudflareForDev();...
ここまで設定できれば Next.js からアクセスできるようになります 🎉
いい感じに型を設定したいですね
'use server'import { D1Database } from '@cloudflare/workers-types'import { getCloudflareContext } from '@opennextjs/cloudflare'const db = (getCloudflareContext().env as any).__DB as D1Database
getCloudflareContext の型補完について
上記のように any を用いらずに、環境変数の型を補完することができます
詳しくは以下の記事を参照ください
こんな感じでユーティリティを用意しておくと便利です 😋
'use server'import { D1Database } from '@cloudflare/workers-types'import { getCloudflareContext } from '@opennextjs/cloudflare'export const getD1Session = async () => {if (process.env.DB) {return process.env.DB} else {try {return (getCloudflareContext().env as any).__DB as D1Database} catch (e) {console.error(e)return null}}}
おわりに
Cloudflare D1 が使えると、プロダクトの幅が大きく広がるので使い倒したいですね 🐶