Open5
remixとD1でTODOアプリを作る
リポジトリはこれ。いまから作っていく
プロジェクト作成
公式テンプレートから作成
npx create-remix@latest --template remix-run/remix/templates/cloudflare
インストールしたパッケージは以下
package.json
{
"name": "remix-d1-todo-app",
"private": true,
"sideEffects": false,
"type": "module",
"scripts": {
"build": "remix vite:build",
"deploy": "wrangler pages deploy ./build/client",
"dev": "remix vite:dev",
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
"start": "wrangler pages dev ./build/client",
"tsc": "tsc",
"typegen": "wrangler types"
},
"dependencies": {
"@conform-to/react": "^1.0.6",
"@conform-to/zod": "^1.0.6",
"@radix-ui/react-slot": "^1.0.2",
"@remix-run/cloudflare": "^2.8.1",
"@remix-run/cloudflare-pages": "^2.8.1",
"@remix-run/react": "^2.8.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"isbot": "^4.1.0",
"lucide-react": "^0.365.0",
"miniflare": "^3.20231030.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwind-merge": "^2.2.2",
"tailwindcss-animate": "^1.0.7",
"zod": "^3.22.4"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20230518.0",
"@remix-run/dev": "^2.8.1",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"autoprefixer": "^10.4.19",
"eslint": "^8.38.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"node-fetch": "^3.3.2",
"postcss": "^8.4.38",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.13",
"remix-development-tools": "^4.1.4",
"tailwindcss": "^3.4.3",
"typescript": "^5.1.6",
"vite": "^5.1.0",
"vite-tsconfig-paths": "^4.2.1",
"wrangler": "^3.24.0"
},
"engines": {
"node": ">=18.0.0"
}
}
デプロイする(先にビルドすること忘れず)
❯ npm run deploy
> deploy
> wrangler pages deploy ./build/client
▲ [WARNING] Pages now has wrangler.toml support.
We detected a configuration file at
/Users/takidakeiichiro/ghq/github.com/otaki0413/remix-d1-todo-app/wrangler.toml
but it is missing the "pages_build_output_dir" field, required by Pages.
If you would like to use this configuration file to deploy your project,
please use "pages_build_output_dir" to specify the directory of static
files to upload.
Ignoring configuration file for now, and proceeding with project deploy.
No project specified. 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-d1-todo-app
✔ Enter the production branch name: … main
✨ Successfully created the 'remix-d1-todo-app' project.
✨ Compiled Worker successfully
🌍 Uploading... (8/8)
✨ Success! Uploaded 8 files (3.60 sec)
✨ Uploading Functions bundle
✨ Deployment complete! Take a peek over at https://faa34ce4.remix-d1-todo-app.pages.dev
D1の設定
-
wrangler
コマンドでtodo-app
という名前でDB作成
❯ npx wrangler d1 create todo-app
⛅️ wrangler 3.48.0
-------------------
✅ Successfully created DB 'todo-app' in region APAC
Created your new D1 database.
[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "todo-app"
database_id = "<データベースID>"
wrangler.toml
にコピペ
wrangler.toml
[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "todo-app"
database_id = "<データベースID>"
npmスクリプトよりwrangler types
を実行して、型ファイル作成
これはwrangler.toml
が元になっている
worker-configuration.d.ts
// Generated by Wrangler on Sun Apr 07 2024 16:28:19 GMT+0900 (Japan Standard Time)
// by running `wrangler types`
interface Env {
DB: D1Database;
}
ダッシュボードよりバインディング設定をする
下記スクラップ参考
Drizzle ORMの導入 + マイグレーション適用
パッケージインストール
npm i drizzle-orm
npm i -D drizzle-kit
スキーマを作成する(SQLiteの型は https://orm.drizzle.team/docs/column-types/sqlite を参考)
schema.server.ts
import { sql } from "drizzle-orm";
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const todos = sqliteTable("todos", {
id: integer("id").primaryKey(),
text: text("text").notNull(),
done: integer("done", { mode: "boolean" }),
userId: integer("userId").references(() => users.id),
});
export const users = sqliteTable("users", {
id: integer("id").primaryKey(),
email: text("email").unique().notNull(),
name: text("name"),
createdAt: text("createdAt")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
updatedAt: text("updatedAt")
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
});
プロジェクト直下にDrizzleの設定ファイルdrizzle.config.ts
を作成しておく
drizzle.config.ts
import type { Config } from "drizzle-kit";
export default {
schema: "app/drizzle/schema.server.ts",
out: "app/drizzle/migrations",
} satisfies Config;
npmスクリプトを設定 + 実行
package.json
"scripts": {
"drizzle:update": "drizzle-kit generate:sqlite" 👈️ これ!
},
❯ npm run drizzle:update
> drizzle:update
> drizzle-kit generate:sqlite
drizzle-kit: v0.20.14
drizzle-orm: v0.30.7
No config path provided, using default 'drizzle.config.ts'
Reading config file '/Users/takidakeiichiro/ghq/github.com/otaki0413/remix-d1-todo-app/drizzle.config.ts'
2 tables
todos 4 columns 0 indexes 1 fks
users 5 columns 1 indexes 0 fks
ローカルにマイグレーション適用(オプションなし)
❯ npx wrangler d1 migrations apply todo-app
⛅️ wrangler 3.48.0
-------------------
Migrations to be applied:
┌──────────────────────────────┐
│ name │
├──────────────────────────────┤
│ 0000_silent_black_knight.sql │
└──────────────────────────────┘
? About to apply 1 migration(s)
✔ 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 todo-app (361dd76e-3885-4552-ac43-d725014ad9b4) from .wrangler/state/v3/d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.
┌──────────────────────────────┬────────┐
│ name │ status │
├──────────────────────────────┼────────┤
│ 0000_silent_black_knight.sql │ ✅ │
└──────────────────────────────┴────────┘
リモートに適用(--remoteオプションつける)
❯ npx wrangler d1 migrations apply todo-app --remote
⛅️ wrangler 3.48.0
-------------------
Migrations to be applied:
┌──────────────────────────────┐
│ name │
├──────────────────────────────┤
│ 0000_silent_black_knight.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
🌀 Parsing 4 statements
🌀 Executing on remote database todo-app (361dd76e-3885-4552-ac43-d725014ad9b4):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 4 commands in 0.7379ms
┌──────────────────────────────┬────────┐
│ name │ status │
├──────────────────────────────┼────────┤
│ 0000_silent_black_knight.sql │ ✅ │
└──────────────────────────────┴────────┘
テーブルできてるね!
参考