月曜日, 5月 5, 2025
ホームニューステックニュース遂に Cloudflare + Next.js(OpenNext) + Prisma 6.7.0(No Rust) が動く時代が来た

遂に Cloudflare + Next.js(OpenNext) + Prisma 6.7.0(No Rust) が動く時代が来た



現状たぶんこれが一番安いと思います。(※個人開発前提のスタックです)

実現したこと

  • opennext for cloudflare
  • prisma (no-rust, no-engine)
  • prisma-postgres (free plan)

つまり Cloudflare 上で Next.js を動かして、現実的なビルドサイズで Prisma を動かせました。

自分の手元のビルドサイズです。

┌ ○ /                                      149 B         102 kB
├ ○ /_not-found                            978 B         103 kB
├ ○ /prisma-test                           149 B         102 kB
# ...
+ First Load JS shared by all             102 kB
  ├ chunks/770-76939705ff65587a.js       46.5 kB
  ├ chunks/96e220d1-21a0fdc894793ec0.js  53.2 kB
  └ other shared chunks (total)          1.89 kB

今まではこれが数十 MB~あり、そもそも opennext では色々絡まってビルド不可能だった状態が解消されます。

https://github.com/opennextjs/opennextjs-cloudflare/issues/139

今までのあらすじ(読まなくてもいい)

Next.js + Prisma + Cloudflare には苦難の歴史があります。

  • RSC を使うのに Next.js を使いたいが…
    • 素の next.js は当然 cloudflare env にアクセスできない
    • opennext for cloudflare でできるようになった
  • prisma-wasm 版はバンドルサイズに難がある(free-plan ギリギリ)
    • paid でも多少コードを書くと超過するかも
  • という事情が色々あって Prisma 自体が Rust から TS で書き直されている
  • prisma 6.7.0 で no rust 版のプレビュー版がでた

これらがやっと噛み合って動くようになったのが今

Optional: prisma-postgres で DB をホスティング

今回、自分は prisma-postgrss ホスティングサービス(無料枠)を使いました。

すでにある DB やローカルにある postgres に繋ぐ場合は不要ですが、今回は リモート DB に、ローカルのドライバ抜きで 繋ぐ検証なので、これを優先します。

https://www.prisma.io/postgres

設定ポチポチやって、 東京のリージョンを選択しつつ、 DATABASE_URL だけメモっておいてください。

同等の設定ができるなら supabase でも何でも構いません。

OpenNext for Cloudflare

https://opennext.js.org/

open といいつつ、ほぼ Cloudflare で Next.js を動かすプロジェクトと理解して大丈夫です。多少 AWS 向けのバインディングがあります。 実質的に next-on-pages の後継です。

next-on-pages はフルビルドしないと cloudflare env につなげませんでしたが、 opennext は開発環境でも miniflare を通じて env の各種バインディングにアクセス可能です。

コード例

import { getCloudflareContext } from "@opennextjs/cloudflare";
export async function GET(request) {
  let responseText = "Hello World";
  const ctx = await getCloudflareContext({ async: true });
  const myKv = ctx.env.MY_KV_NAMESPACE;
  await myKv.put("foo", "bar");
  const foo = await myKv.get("foo");
  return new Response(foo);
}

プロジェクト生成

$ npm create cloudflare@latest -- my-next-app --framework=next --platform=workers

これは普通の Next.js がカスタマイズされたもので、一度 next build してから npx opennextjs-cloudflare build && npx opennextjs-cloudflare upload のように cloudflare 用のアダプタを差し込んで多段でビルドします。

プロジェクト固有のセットアップとして、 next.config.mjsinitOpenNextCloudflareForDev() を呼ぶ必要があります。


const nextConfig = {};

export default nextConfig;

import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
initOpenNextCloudflareForDev();

あとは普通の next.js と 大きな違いはありませんが、現状 "use cache"; は未対応です。

https://opennext.js.org/cloudflare

(今後も vercel 側の新機能の追従は遅くなると思われます)

Prisma (No-Rust) Setup

先にセットアップした prisma-postgres に対して、 prisma の環境を設定します。

$ npm add prisma @prisma/client -D
$ npx prisma init

.envDATABASE_URL を設定します。

DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key="

prisma/schema.prisma に以下のファイルを設定。

generator client {
  provider = "prisma-client-js"
  previewFeatures = ["queryCompiler", "driverAdapters"]
  output   = "../src/generated/prisma"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        String   @id @default(cuid())
  name      String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

大事なのは ["queryCompiler", "driverAdapters"] の部分で、他はどうでもいいです。

この時点で本番 DB につながるはずなので、コードを生成してマイグレーションします。

$ npx prisma generate --no-engine
$ npx prisma migrate dev

--no-engine 指定によって、Prisma のランタイムアダプタが生成コードから省かれます。Rust 版はここで .wasm を読み込んで、バンドルサイズの問題が発生していました。

(ローカルマイグレーションに npm add @prisma/adapter-pg も必要かも?あとで確認)

Prisma を実行するコードを書く

src/db.ts

import { PrismaClient } from "./generated/prisma";
export const prisma = new PrismaClient();

これを読み込んで、 async function component から実行。


import { prisma } from "../../db";
export default async function Page() {
  const users = await prisma.user.findFirst({});
  
  
  
  
  
  
  
  return (
    div>
      h1>Welcome to the Prisma Test Page/h1>
      pre>{JSON.stringify(users, null, 2)}/pre>
    /div>
  );
}

これで自分のローカル+プロダクション環境で両方動きました。

デプロイする場合


$ npx opennextjs-cloudflare build && npx opennextjs-cloudflare deploy

備考: ローカルの開発環境の postgres に繋ぐ

本番に直で繋ぎたくない場合の処理です。

最初に compose.yaml で適当にコンテナを建てるとします。

services:
  postgres:
    image: "postgres:16.1"
    restart: always
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "postgres"

@prisma/adapter-pg でアダプタをセットアップして、これを client の初期化に渡します。

import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "./generated/prisma";
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
export const prisma = new PrismaClient({ adapter });

(このとき --no-engine 指定できないかも)

残る課題

  • まだ preview release
  • opennext の枯れてなさ+多段ビルドの複雑性
  • sqlite は better-sqlite3 の実験的なサポートはあるが、 d1 バインディングがない

まとめ

本当に安く済ませたいときの d1 バインディングがなかったりするんですが、一応現実的に動く状態が来た、と言える状態が来たんじゃないでしょうか。

RSC も vercel + next.js の専売特許だったのが、やっと開放されつつあります。

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 2

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -

Most Popular

Recent Comments