Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update cloudflare-d1 template to not use "@hiogawa/vite-node-miniflare" #63

Merged
merged 3 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions cloudflare-d1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,24 @@ npm run build

Deployment is done using the Wrangler CLI.

To deploy directly to production:
First, you need to create a d1 database in Cloudflare.

```sh
npx wrangler deploy
npx wrangler d1 create <name-of-your-database>
```

Be sure to update the `wrangler.toml` file with the correct database name and id.

You will also need to [update the `drizzle.config.ts` file](https://orm.drizzle.team/docs/guides/d1-http-with-drizzle-kit), and then run the production migration:

```sh
npm run db:migrate-production
```

To build and deploy directly to production:

```sh
npm run deploy
```

To deploy a preview URL:
Expand Down
12 changes: 4 additions & 8 deletions cloudflare-d1/app/routes/home.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { database } from "~/database/context";
import * as schema from "~/database/schema";

import type { Route } from "./+types/home";
Expand All @@ -11,7 +10,7 @@ export function meta({}: Route.MetaArgs) {
];
}

export async function action({ request }: Route.ActionArgs) {
export async function action({ request, context }: Route.ActionArgs) {
const formData = await request.formData();
let name = formData.get("name");
let email = formData.get("email");
Expand All @@ -25,18 +24,15 @@ export async function action({ request }: Route.ActionArgs) {
return { guestBookError: "Name and email are required" };
}

const db = database();
try {
await db.insert(schema.guestBook).values({ name, email });
await context.db.insert(schema.guestBook).values({ name, email });
} catch (error) {
return { guestBookError: "Error adding to guest book" };
}
}

export async function loader({ context }: Route.LoaderArgs) {
const db = database();

const guestBook = await db.query.guestBook.findMany({
const guestBook = await context.db.query.guestBook.findMany({
columns: {
id: true,
name: true,
Expand All @@ -45,7 +41,7 @@ export async function loader({ context }: Route.LoaderArgs) {

return {
guestBook,
message: context.VALUE_FROM_CLOUDFLARE,
message: context.cloudflare.env.VALUE_FROM_CLOUDFLARE,
};
}

Expand Down
17 changes: 0 additions & 17 deletions cloudflare-d1/database/context.ts

This file was deleted.

32 changes: 32 additions & 0 deletions cloudflare-d1/load-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { drizzle, type DrizzleD1Database } from "drizzle-orm/d1";
import * as schema from "./database/schema";
import type { ExecutionContext } from "@cloudflare/workers-types";
import type { AppLoadContext } from "react-router";

declare global {
interface CloudflareEnvironment extends Env {}
}

declare module "react-router" {
export interface AppLoadContext {
cloudflare: {
env: CloudflareEnvironment;
ctx: Omit<ExecutionContext, "props">;
};
db: DrizzleD1Database<typeof schema>;
}
}

type GetLoadContextArgs = {
request: Request;
context: Pick<AppLoadContext, "cloudflare">;
};

export function getLoadContext({ context }: GetLoadContextArgs) {
const db = drizzle(context.cloudflare.env.DB, { schema });

return {
cloudflare: context.cloudflare,
db,
};
}
2 changes: 1 addition & 1 deletion cloudflare-d1/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"db:migrate-production": "dotenv -- drizzle-kit migrate",
"dev": "react-router dev",
"start": "wrangler dev",
"deploy": "npm run build && wrangler deploy",
"typecheck": "react-router typegen && tsc -b"
},
"dependencies": {
Expand All @@ -21,7 +22,6 @@
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20241112.0",
"@hiogawa/vite-node-miniflare": "0.1.1",
"@react-router/dev": "*",
"@types/node": "^20",
"@types/react": "^19.0.1",
Expand Down
4 changes: 3 additions & 1 deletion cloudflare-d1/tsconfig.cloudflare.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"app/**/.server/**/*",
"app/**/.client/**/*",
"database/**/*",
"workers/**/*"
"workers/**/*",
"load-context.ts",
"worker-configuration.d.ts"
],
"compilerOptions": {
"composite": true,
Expand Down
8 changes: 7 additions & 1 deletion cloudflare-d1/tsconfig.node.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
{
"extends": "./tsconfig.json",
"include": ["tailwind.config.ts", "vite.config.ts"],
"include": [
"tailwind.config.ts",
"vite.config.ts",
"database/**/*",
"load-context.ts",
"worker-configuration.d.ts"
],
"compilerOptions": {
"composite": true,
"strict": true,
Expand Down
15 changes: 4 additions & 11 deletions cloudflare-d1/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { vitePluginViteNodeMiniflare } from "@hiogawa/vite-node-miniflare";
import { reactRouter } from "@react-router/dev/vite";
import { cloudflareDevProxy } from "@react-router/dev/vite/cloudflare";
import autoprefixer from "autoprefixer";
import tailwindcss from "tailwindcss";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
import { getLoadContext } from "./load-context";

export default defineConfig(({ isSsrBuild }) => ({
build: {
Expand All @@ -21,7 +22,6 @@ export default defineConfig(({ isSsrBuild }) => ({
ssr: {
target: "webworker",
noExternal: true,
external: ["node:async_hooks"],
resolve: {
conditions: ["workerd", "browser"],
},
Expand All @@ -37,15 +37,8 @@ export default defineConfig(({ isSsrBuild }) => ({
},
},
plugins: [
vitePluginViteNodeMiniflare({
entry: "./workers/app.ts",
miniflareOptions: (options) => {
options.compatibilityDate = "2024-11-18";
options.compatibilityFlags = ["nodejs_compat"];
options.d1Databases = { DB: "your-database-id" };
// match where wrangler applies migrations to
options.d1Persist = ".wrangler/state/v3/d1";
},
cloudflareDevProxy({
getLoadContext,
}),
reactRouter(),
tsconfigPaths(),
Expand Down
6 changes: 6 additions & 0 deletions cloudflare-d1/worker-configuration.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Generated by Wrangler by running `wrangler types`

interface Env {
VALUE_FROM_CLOUDFLARE: "Hello from Cloudflare";
DB: D1Database;
}
28 changes: 7 additions & 21 deletions cloudflare-d1/workers/app.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,18 @@
import { drizzle } from "drizzle-orm/d1";
import { getLoadContext } from "load-context";
import { createRequestHandler } from "react-router";

import { DatabaseContext } from "~/database/context";
import * as schema from "~/database/schema";

interface CloudflareEnvironment {
DB: D1Database;
}

declare module "react-router" {
export interface AppLoadContext {
VALUE_FROM_CLOUDFLARE: string;
}
}

const requestHandler = createRequestHandler(
// @ts-expect-error - virtual module provided by React Router at build time
() => import("virtual:react-router/server-build"),
import.meta.env.MODE
);

export default {
fetch(request, env) {
const db = drizzle(env.DB, { schema });
return DatabaseContext.run(db, () =>
requestHandler(request, {
VALUE_FROM_CLOUDFLARE: "Hello from Cloudflare",
})
);
fetch(request, env, ctx) {
const loadContext = getLoadContext({
request,
context: { cloudflare: { env, ctx } },
});
return requestHandler(request, loadContext);
},
} satisfies ExportedHandler<CloudflareEnvironment>;
3 changes: 3 additions & 0 deletions cloudflare-d1/wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ compatibility_flags = ["nodejs_compat"]
main = "./build/server/index.js"
assets = { directory = "./build/client/" }

[vars]
VALUE_FROM_CLOUDFLARE = "Hello from Cloudflare"

[[d1_databases]]
binding = "DB"
database_name = "your-database-name"
Expand Down
4 changes: 2 additions & 2 deletions cloudflare/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ npm run build

Deployment is done using the Wrangler CLI.

To deploy directly to production:
To build and deploy directly to production:

```sh
npx wrangler deploy
npm run deploy
```

To deploy a preview URL:
Expand Down
1 change: 1 addition & 0 deletions cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"build": "react-router build",
"dev": "react-router dev",
"start": "wrangler dev",
"deploy": "npm run build && wrangler deploy",
"typecheck": "react-router typegen && tsc -b"
},
"dependencies": {
Expand Down
1 change: 0 additions & 1 deletion cloudflare/workers/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const requestHandler = createRequestHandler(

export default {
fetch(request, env, ctx) {
console.log("yo");
return requestHandler(request, {
cloudflare: { env, ctx },
});
Expand Down
Loading
Loading