Remix Vite × Drizzle × Cloudflare D1 スタックを試してみる
はじめに
今後、個人開発で使いたい技術スタックなので下記の記事を参考にして、
Remix Vite、Drizzle、Cloudflare、D1を使った簡易的に動くものを作ってみる。
プロジェクト作成 〜 ローカル開発の準備まで
上記サイトに従って、まずは公式テンプレートよりプロジェクト作成する
npx create-remix@latest --template remix-run/remix/templates/vite-cloudflare
早速エラーが出た。公式にtemplates/vite-cloudflare
というリポジトリはないっぽいね。
npx create-remix@latest --template remix-run/remix/templates/vite-cloudflare
remix v2.8.1 💿 Let's build a better website...
dir Where should we create your new project?
remix-vite-drizzle-cloudflare-d1
◼ Template: Using remix-run/remix/templates/vite-cloudflare...
██████ Template copying...
▲ Oh no! The path "templates/vite-cloudflare" was not found in this GitHub repo.
公式ドキュメントを見たところ、templates/cloudflare
に変わってたのでこちらを使用
npx create-remix@latest --template remix-run/remix/templates/cloudflare
今回はうまくいった👍
npx create-remix@latest --template remix-run/remix/templates/cloudflare
remix v2.8.1 💿 Let's build a better website...
dir Where should we create your new project?
remix-vite-drizzle-cloudflare-d1
◼ Template: Using remix-run/remix/templates/cloudflare...
✔ Template copied
git Initialize a new git repository?
Yes
deps Install dependencies with npm?
Yes
✔ Dependencies installed
✔ Git initialized
done That's it!
Enter your project directory using cd ./remix-vite-drizzle-cloudflare-d1
Check out README.md for development and deploy instructions.
Join the community at https://rmx.as/discord
ドキュメントによると、アプリをローカルで起動させる方法としては下記の2つがあるようで。
# Viteの場合
remix vite:dev
# Wranglerの場合
remix vite:build # build app before running wrangler
wrangler pages dev ./build/client
下記のような記載も書かれていた。
最終的にはCloudflarePagesにデプロイするので、Wrangler
を使ったローカル開発をしたほうがいいのかもしれん。いったん従ってみよう。
While Vite provides a better development experience, Wrangler provides closer emulation of the Cloudflare environment by running your server code in Cloudflare's workerd runtime instead of Node.
(日本語訳)> Viteはより良い開発体験を提供しますが、WranglerはNodeの代わりにCloudflareのworkerdランタイムでサーバーコードを実行することで、よりCloudflare環境に近いエミュレーションを提供します。
まずはビルドする
npm run build
> build
> remix vite:build
vite v5.2.7 building for production...
✓ 83 modules transformed.
build/client/.vite/manifest.json 1.02 kB │ gzip: 0.29 kB
build/client/assets/_index-CMV5dfNo.js 0.72 kB │ gzip: 0.42 kB
build/client/assets/root-CdN9S7dO.js 1.44 kB │ gzip: 0.84 kB
build/client/assets/jsx-runtime-BlSqMCxk.js 8.09 kB │ gzip: 3.04 kB
build/client/assets/entry.client-CmAxv4Nw.js 57.28 kB │ gzip: 19.52 kB
build/client/assets/components-CT78CVRP.js 178.40 kB │ gzip: 57.10 kB
✓ built in 858ms
vite v5.2.7 building SSR bundle for production...
✓ 5 modules transformed.
build/server/.vite/manifest.json 0.15 kB
build/server/index.js 4.63 kB
✓ built in 27ms
次にwrangler
コマンドで起動させようとしたが、そもそもコマンド自体が入っていなかった。
wrangler pages dev ./build/client
zsh: command not found: wrangler
wrangler
コマンドをインストールする
※あとから見返したら、すでにインストールされていたのでしなくてもいい。
npm install wrangler --save-dev
再度、ローカルで立ち上げてみるとうまくいった。
npm run start
> start
> wrangler pages dev ./build/client
▲ [WARNING] No compatibility_date was specified. Using today's date: 2024-03-31.
Pass it in your terminal:
--compatibility-date=2024-03-31
See https://developers.cloudflare.com/workers/platform/compatibility-dates/ for more information.
Compiling worker to "/Users/takidakeiichiro/Documents/code/Remix-Project/remix-vite-drizzle-cloudflare-d1/.wrangler/tmp/pages-rY3c5G/functionsWorker-0.8071847245483197.mjs"...
✨ Compiled Worker successfully
⛅️ wrangler 3.41.0
-------------------
[wrangler:inf] Ready on http://localhost:8787
⎔ Starting local server...
とりあえず作成したリポジトリはこちらです。
Drizzle ORM のセットアップ
まずDrizzleとは?
- Drizzle は軽量でモダンな TypeScript ORM
- 設計上サーバーレスに対応しており、NodeJS、Bun、Deno、Cloudflare Workers、Supabase functions、あらゆるエッジランタイム、そしてブラウザーなど、主要なJSランタイムで動作する。
実際にインストールしてみる
必要なパッケージは以下の2つ
npm i drizzle-orm
npm i -D drizzle-kit
drizzle-kit
- SQLマイグレーション自動生成とラピッドプロトタイピングのためのCLIコンパニオン。
- スキーマを異なるファイルに分割したり、1つのプロジェクトで異なるDB用の複数スキーマを作成できる。
スキーマの作成
インストールしたら、基本的なスキーマを書いてみる。
import {
sqliteTable,
text,
integer,
} from "drizzle-orm/sqlite-core"
export const resources = sqliteTable("resources", {
id: integer("id").primaryKey(),
title: text("title").notNull(),
href: text("href").notNull(),
})
スクリプト設定 + 実行
スキーマに基づいて型を生成するために、drizzle-kit
を使用する。
package.json
にマイグレーションを実行するスクリプトを追加
{
"scripts": {
"drizzle:update": "drizzle-kit generate:sqlite --out ./app/drizzle/migrations --schema ./app/drizzle/schema.server.ts"
}
}
スクリプト実行すると、migrations
フォルダが生成され、その配下にマイグレーションファイルができる
npm run drizzle:update
> drizzle:update
> drizzle-kit generate:sqlite --out ./app/drizzle/migrations --schema ./app/drizzle/schema.server.ts
drizzle-kit: v0.20.14
drizzle-orm: v0.30.6
1 tables
resources 3 columns 0 indexes 0 fks
[✓] Your SQL migration file ➜ app/drizzle/migrations/0000_worthless_cardiac.sql 🚀
このあたりが参考になるか
D1のセットアップ
データベース作成
下記コマンドでデータベースを新規作成できる
npx wrangler d1 create <データベース名>
test-db
という名前で試しに作る
Cloudflareのダッシュボードを確認したところ、ちゃんとできてるみたい
データベース作成時にコマンド出力された内容をwrangler.toml
に貼り付ける。
漏れてほしくいない情報だと思うので、本ファイルを.gitignore
にも追記しておく。
[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "test-db"
database_id = "データベースID"
migrations_dir="./app/drizzle/migrations" 👈️ これは追記しておく
データベースのインターフェース作成
データベースが存在することをTypeScriptに伝えるために、下記コマンドでインターフェース生成する
npx wrangler types
⛅️ wrangler 3.41.0
-------------------
interface Env {
DB: D1Database;
}
すると、worker-configuration.d.ts
ができる
// Generated by Wrangler on Sun Mar 31 2024 15:21:05 GMT+0900 (Japan Standard Time)
// by running `wrangler types`
interface Env {
DB: D1Database;
}
その後、プロジェクト作成時から存在するload-context.ts
に、空のEnv
インターフェースがあるが、
上記で生成されたものを機能させたいのでこちらは削除しておく。
import { type PlatformProxy } from "wrangler";
- interface Env {}
type Cloudflare = Omit<PlatformProxy<Env>, "dispose">;
declare module "@remix-run/cloudflare" {
interface AppLoadContext {
cloudflare: Cloudflare;
}
}
PagesFunctionsとD1の紐づけ
プロジェクトの[setting] > [Functions] > [D1 database bindings]の部分で設定する。
とりあえず変数名はDB
として、値はD1のデータベースを選択する。
この設定により、本番の Pages Functions(Workers) からも D1 へ接続ができるようになる。
マイグレーションの適用
ローカルでの適用 --local
マイグレーションの一覧確認
npx wrangler d1 migrations list test-db
⛅️ wrangler 3.41.0
-------------------
Migrations to be applied:
┌────────────────────────────┐
│ Name │
├────────────────────────────┤
│ 0000_worthless_cardiac.sql │
└────────────────────────────┘
マイグレーションが作成済みなので、まずはローカル環境に適用させる。--local
忘れずに。
npx wrangler d1 migrations apply test-db --local
⛅️ wrangler 3.41.0
-------------------
Migrations to be applied:
┌────────────────────────────┐
│ name │
├────────────────────────────┤
│ 0000_worthless_cardiac.sql │
└────────────────────────────┘
✔ About to apply 1 migration(s)
Your database may not be available to serve requests during the migration, continue? … yes
🌀 Mapping SQL input into an array of statements
🌀 Executing on local database test-db (635dc2a7-6ff1-4154-b7d7-67b64f186783) from .wrangler/state/v3/d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.
┌────────────────────────────┬────────┐
│ name │ status │
├────────────────────────────┼────────┤
│ 0000_worthless_cardiac.sql │ ✅ │
└────────────────────────────┴────────┘
再度マイグレーション確認したが、もう残ってないのでOK。
npx wrangler d1 migrations list test-db
⛅️ wrangler 3.41.0
-------------------
✅ No migrations to apply!
本番での適用
--local
オプションを外す (👈️これ機能しない)
npx wrangler d1 migrations apply test-db
⛅️ wrangler 3.41.0
-------------------
✅ No migrations to apply!
あれ、マイグレーションがない???本番DBに適用されると思っていたが想定していた動きと違う。
いったんドキュメント見るか。
下記はマイグレーション適用のコマンド。
wrangler d1 migrations apply <DATABASE_NAME> [OPTIONS]
-
--local
- デフォルト設定
- ローカルに永続化されたD1データベースに対して、未適用のマイグレーションを実行する。
-
--remote
- リモート D1 データベースに対して、未適用のマイグレーションを実行する
--remote
つけて再度実行したらうまくいった!✨
npx wrangler d1 migrations apply test-db --remote
デプロイ
下記コマンドでデプロイできる。
npm run deploy
> deploy
> wrangler pages deploy ./build/client
No project selected. Would you like to create one or use an existing project?
❯ Create a new project
Use an existing project
✔ Enter the name of your new project: … remix-vite-drizzle-cloudflare-d1
✔ Enter the production branch name: … main
✨ Successfully created the 'remix-vite-drizzle-cloudflare-d1' project.
✨ Compiled Worker successfully
🌎 Uploading... (8/8)
✨ Success! Uploaded 8 files (2.04 sec)
✨ Uploading Functions bundle
✨ Deployment complete! Take a peek over at https://2ae1b2ba.remix-vite-drizzle-cloudflare-d1.pages.dev
最終行のリンクより、アクセスできればデプロイは完了!
参考になったサイト