Skip to content

Commit

Permalink
Support WebAssembly modules (#8031)
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesopstad authored Feb 10, 2025
1 parent 0c0374c commit 07db54c
Show file tree
Hide file tree
Showing 31 changed files with 764 additions and 241 deletions.
5 changes: 5 additions & 0 deletions .changeset/wild-schools-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudflare/vite-plugin": minor
---

Add support for Wasm (WebAssembly) modules.
3 changes: 3 additions & 0 deletions packages/vite-plugin-cloudflare/playground/prisma/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
# Keep environment variables out of version control
.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { expect, test } from "vitest";
import { getJsonResponse } from "../../__test-utils__";

// Need to remove the `.wrangler` directory and run the following commands before the tests.
// I'm not sure how to do this with our testing setup so have skipped the test for now.
// const commands = [
// `pnpm wrangler d1 migrations apply prisma-demo-db --local`,
// `pnpm wrangler d1 execute prisma-demo-db --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('[email protected]', 'Jane Doe (Local)');" --local`,
// ];

test.skip("runs D1 query using Prisma", async () => {
const result = await getJsonResponse();
expect(result).toEqual([
{ id: 1, email: "[email protected]", name: "Jane Doe (Local)" },
]);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- CreateTable
CREATE TABLE "User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"email" TEXT NOT NULL,
"name" TEXT
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
27 changes: 27 additions & 0 deletions packages/vite-plugin-cloudflare/playground/prisma/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@playground/prisma",
"private": true,
"type": "module",
"scripts": {
"prebuild": "pnpm generate",
"build": "vite build --app",
"check:types": "tsc --build",
"predev": "pnpm generate",
"dev": "vite dev",
"generate": "pnpm prisma generate",
"migrate-db": "pnpm wrangler d1 migrations apply prisma-demo-db --local",
"preview": "vite preview",
"seed-db": "pnpm wrangler d1 execute prisma-demo-db --command \"INSERT INTO \"User\" (\"email\", \"name\") VALUES ('[email protected]', 'Jane Doe (Local)');\" --local"
},
"devDependencies": {
"@cloudflare/vite-plugin": "workspace:*",
"@cloudflare/workers-tsconfig": "workspace:*",
"@cloudflare/workers-types": "^4.20250121.0",
"@prisma/adapter-d1": "^6.3.0",
"@prisma/client": "^6.3.0",
"prisma": "^6.3.0",
"typescript": "catalog:default",
"vite": "catalog:vite-plugin",
"wrangler": "catalog:vite-plugin"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
// Default output directory does not work with Vite. See https://github.com/vitejs/vite/issues/19036#issuecomment-2558791944
output = "../node_modules/@prisma/client-generated"
}

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

model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
16 changes: 16 additions & 0 deletions packages/vite-plugin-cloudflare/playground/prisma/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { PrismaD1 } from "@prisma/adapter-d1";
import { PrismaClient } from "@prisma/client-generated";

interface Env {
DB: D1Database;
}

export default {
async fetch(request, env) {
const adapter = new PrismaD1(env.DB);
const prisma = new PrismaClient({ adapter });
const users = await prisma.user.findMany();

return Response.json(users);
},
} satisfies ExportedHandler<Env>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.node.json" },
{ "path": "./tsconfig.worker.json" }
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["@cloudflare/workers-tsconfig/base.json"],
"include": ["vite.config.ts", "__tests__"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["@cloudflare/workers-tsconfig/worker.json"],
"include": ["src"]
}
9 changes: 9 additions & 0 deletions packages/vite-plugin-cloudflare/playground/prisma/turbo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "http://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["dist/**"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { cloudflare } from "@cloudflare/vite-plugin";
import { defineConfig } from "vite";

export default defineConfig({
plugins: [cloudflare()],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name = "worker"
main = "./src/index.ts"
compatibility_date = "2024-12-30"
compatibility_flags = ["nodejs_compat"]

[[d1_databases]]
binding = "DB"
database_name = "prisma-demo-db"
database_id = "local"
11 changes: 11 additions & 0 deletions packages/vite-plugin-cloudflare/playground/wasm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# WebAssembly Playground

The `minimal.wasm` file in the `src` directory was generated from the following C code:

```c
#include <stdint.h>

int32_t add(int32_t a, int32_t b) {
return a + b;
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { expect, test } from "vitest";
import { getJsonResponse } from "../../__test-utils__";

test("imports and instantiates WebAssembly", async () => {
const result = await getJsonResponse();
expect(result).toEqual({ result: 7 });
});
19 changes: 19 additions & 0 deletions packages/vite-plugin-cloudflare/playground/wasm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@playground/wasm",
"private": true,
"type": "module",
"scripts": {
"build": "vite build --app",
"check:types": "tsc --build",
"dev": "vite dev",
"preview": "vite preview"
},
"devDependencies": {
"@cloudflare/vite-plugin": "workspace:*",
"@cloudflare/workers-tsconfig": "workspace:*",
"@cloudflare/workers-types": "^4.20250121.0",
"typescript": "catalog:default",
"vite": "catalog:vite-plugin",
"wrangler": "catalog:vite-plugin"
}
}
10 changes: 10 additions & 0 deletions packages/vite-plugin-cloudflare/playground/wasm/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import wasm from "./minimal.wasm";

export default {
async fetch() {
const instance = await WebAssembly.instantiate(wasm);
const result = instance.exports.add(3, 4);

return Response.json({ result });
},
} satisfies ExportedHandler;
Binary file not shown.
7 changes: 7 additions & 0 deletions packages/vite-plugin-cloudflare/playground/wasm/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.node.json" },
{ "path": "./tsconfig.worker.json" }
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["@cloudflare/workers-tsconfig/base.json"],
"include": ["vite.config.ts", "__tests__"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["@cloudflare/workers-tsconfig/worker.json"],
"include": ["src"]
}
9 changes: 9 additions & 0 deletions packages/vite-plugin-cloudflare/playground/wasm/turbo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "http://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["dist/**"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { cloudflare } from "@cloudflare/vite-plugin";
import { defineConfig } from "vite";

export default defineConfig({
plugins: [cloudflare({ persistState: false })],
});
3 changes: 3 additions & 0 deletions packages/vite-plugin-cloudflare/playground/wasm/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name = "worker"
main = "./src/index.ts"
compatibility_date = "2024-12-30"
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ const cloudflareBuiltInModules = [
"cloudflare:workflows",
];

const defaultConditions = ["workerd", "module", "browser"];

export function createCloudflareEnvironmentOptions(
workerConfig: WorkerConfig,
userConfig: vite.UserConfig,
Expand All @@ -131,7 +133,7 @@ export function createCloudflareEnvironmentOptions(
// dependencies as not external
noExternal: true,
// We want to use `workerd` package exports if available (e.g. for postgres).
conditions: ["workerd", "module", "browser", "development|production"],
conditions: [...defaultConditions, "development|production"],
},
dev: {
createEnvironment(name, config) {
Expand All @@ -142,6 +144,9 @@ export function createCloudflareEnvironmentOptions(
createEnvironment(name, config) {
return new vite.BuildEnvironment(name, config);
},
target: "es2022",
// We need to enable `emitAssets` in order to support additional modules defined by `rules`
emitAssets: true,
outDir: getOutputDirectory(userConfig, environmentName),
ssr: true,
rollupOptions: {
Expand All @@ -163,6 +168,7 @@ export function createCloudflareEnvironmentOptions(
],
esbuildOptions: {
platform: "neutral",
conditions: [...defaultConditions, "development"],
resolveExtensions: [
".mjs",
".js",
Expand Down
3 changes: 3 additions & 0 deletions packages/vite-plugin-cloudflare/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export const ROUTER_WORKER_NAME = "__router-worker__";
export const ASSET_WORKER_NAME = "__asset-worker__";
export const ASSET_WORKERS_COMPATIBILITY_DATE = "2024-10-04";
// TODO: add `Text` and `Data` types (resolves https://github.com/cloudflare/workers-sdk/issues/8022)
export const MODULE_TYPES = ["CompiledWasm"] as const;
export type ModuleType = (typeof MODULE_TYPES)[number];
Loading

0 comments on commit 07db54c

Please sign in to comment.