Skip to content

Commit f927adc

Browse files
update waku c3 (#14381)
Co-authored-by: Dario Piotrowicz <dario@cloudflare.com>
1 parent 07cd86c commit f927adc

8 files changed

Lines changed: 142 additions & 20 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"create-cloudflare": patch
3+
---
4+
5+
Scaffold the Cloudflare-specific Waku files in the C3 script instead of relying on an external example
6+
7+
The Waku template now runs the default `create-waku` generator and overlays the Cloudflare-specific files (`wrangler.jsonc`, the Workers entrypoint `src/waku.server.tsx`, the Cloudflare `waku.config.ts`, and the `public/_headers` / `public/404.html` static assets) via `copyFiles`, installing the extra build dependencies and removing the redundant trailing-slash dev middleware in `configure`. This removes the dependency on the external `wakujs/waku-examples` repository for the scaffolded project content.

packages/create-cloudflare/templates/waku/c3.ts

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,54 @@
1+
import { resolve } from "node:path";
2+
import { logRaw } from "@cloudflare/cli-shared-helpers";
3+
import { brandColor, dim } from "@cloudflare/cli-shared-helpers/colors";
4+
import { spinner } from "@cloudflare/cli-shared-helpers/interactive";
15
import { runFrameworkGenerator } from "frameworks/index";
6+
import { removeFile } from "helpers/files";
27
import { detectPackageManager } from "helpers/packageManagers";
8+
import { installPackages } from "helpers/packages";
39
import type { TemplateConfig } from "../../src/templates";
410
import type { C3Context } from "types";
511

612
const { npm } = detectPackageManager();
713

814
const generate = async (ctx: C3Context) => {
15+
// We use the default `create-waku` template and overlay our Cloudflare-specific
16+
// files via `copyFiles`. This avoids depending on an external example repository
17+
// for the scaffolded project content (which could be renamed, moved, or deleted).
918
await runFrameworkGenerator(ctx, [
1019
"--project-name",
1120
ctx.project.name,
12-
"--template",
13-
"07_cloudflare",
21+
// c3 installs dependencies itself once the template files have been copied over
22+
"--skip-install",
1423
]);
24+
25+
logRaw(""); // newline
26+
};
27+
28+
const configure = async (ctx: C3Context) => {
29+
// `npmInstall` has already run with the default Waku template's `package.json`,
30+
// which doesn't include the Cloudflare build dependencies that our overlaid
31+
// `waku.config.ts` and Workers setup need. Install them now (this also adds them
32+
// to `package.json`). `wrangler` is installed separately by `installWrangler()`
33+
// in the main configure flow before this runs.
34+
await installPackages(
35+
["@cloudflare/vite-plugin", "miniflare", "@types/node"],
36+
{
37+
dev: true,
38+
startText: "Installing Cloudflare build dependencies",
39+
doneText: `${brandColor("installed")} ${dim(
40+
"@cloudflare/vite-plugin, miniflare, @types/node"
41+
)}`,
42+
}
43+
);
44+
45+
// The default Waku template ships a Hono trailing-slash dev middleware. On
46+
// Cloudflare this is handled by `html_handling: "drop-trailing-slash"` in
47+
// `wrangler.jsonc` (and `public/_headers`), so remove the redundant middleware.
48+
const s = spinner();
49+
s.start("Removing non-Cloudflare artifacts from template");
50+
removeFile(resolve(ctx.project.path, "src/middleware/no-trailing-slash.ts"));
51+
s.stop(`${brandColor("removed")} ${dim("trailing-slash dev middleware")}`);
1552
};
1653

1754
const config: TemplateConfig = {
@@ -20,12 +57,18 @@ const config: TemplateConfig = {
2057
frameworkCli: "create-waku",
2158
platform: "workers",
2259
displayName: "Waku",
60+
copyFiles: {
61+
path: "./templates",
62+
},
2363
path: "templates/waku",
2464
generate,
65+
configure,
2566
transformPackageJson: async () => ({
2667
scripts: {
2768
deploy: `${npm} run build && wrangler deploy`,
2869
preview: `NODE_ENV=production ${npm} run build && wrangler dev`,
70+
start: `wrangler dev`,
71+
"cf-typegen": `wrangler types`,
2972
},
3073
}),
3174
devScript: "dev",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>Not Found</h1>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/RSC/*
2+
X-Robots-Tag: noindex
3+
/assets/*
4+
Cache-Control: public, max-age=31536000, immutable
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { fsRouter } from 'waku';
2+
import adapter from 'waku/adapters/cloudflare';
3+
4+
export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')), {
5+
handlers: {
6+
// Define additional Cloudflare Workers handlers here
7+
// https://developers.cloudflare.com/workers/runtime-apis/handlers/
8+
// async queue(
9+
// batch: MessageBatch,
10+
// _env: Env,
11+
// _ctx: ExecutionContext,
12+
// ): Promise<void> {
13+
// for (const message of batch.messages) {
14+
// console.log('Received', message);
15+
// }
16+
// },
17+
} satisfies ExportedHandler<Env>,
18+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { cloudflare } from '@cloudflare/vite-plugin';
2+
import babel from '@rolldown/plugin-babel';
3+
import tailwindcss from '@tailwindcss/vite';
4+
import react, { reactCompilerPreset } from '@vitejs/plugin-react';
5+
import { defineConfig } from 'waku/config';
6+
7+
export default defineConfig({
8+
vite: {
9+
environments: {
10+
rsc: {
11+
optimizeDeps: {
12+
include: ['hono/tiny'],
13+
},
14+
build: {
15+
rolldownOptions: {
16+
platform: 'neutral',
17+
},
18+
},
19+
},
20+
ssr: {
21+
optimizeDeps: {
22+
include: ['waku > rsc-html-stream/server'],
23+
},
24+
build: {
25+
rolldownOptions: {
26+
platform: 'neutral',
27+
},
28+
},
29+
},
30+
},
31+
plugins: [
32+
tailwindcss(),
33+
react(),
34+
babel({ presets: [reactCompilerPreset()] }),
35+
cloudflare({
36+
viteEnvironment: { name: 'rsc', childEnvironments: ['ssr'] },
37+
inspectorPort: false,
38+
}),
39+
],
40+
},
41+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"$schema": "node_modules/wrangler/config-schema.json",
3+
"name": "<WORKER_NAME>",
4+
"main": "./src/waku.server",
5+
// nodejs_als is required for Waku server-side request context
6+
// It can be removed if only building static pages
7+
"compatibility_flags": ["nodejs_als"],
8+
// https://developers.cloudflare.com/workers/platform/compatibility-dates
9+
"compatibility_date": "<COMPATIBILITY_DATE>",
10+
"assets": {
11+
// https://developers.cloudflare.com/workers/static-assets/binding/
12+
"binding": "ASSETS",
13+
"directory": "./dist/public",
14+
"html_handling": "drop-trailing-slash"
15+
},
16+
"vars": {
17+
"MAX_ITEMS": 10
18+
},
19+
"rules": [
20+
{
21+
"type": "ESModule",
22+
"globs": ["**/*.js", "**/*.mjs"]
23+
}
24+
],
25+
"no_bundle": true
26+
}

packages/create-cloudflare/templates/waku/wrangler.jsonc

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)