build(cloudflare): add a Cloudflare preview build target

DEPLOY_TARGET now selects the adapter; Netlify stays the default and NODE_ADAPTER
keeps working. Cloudflare compresses in transit, so the Worker build aliases
$lib/server/compression to a pass-through that leaves the streaming body alone.

CI builds and dry-run deploys this target. That is compilation and packaging
coverage only, not a production compatibility gate: native sharp still blocks the
share-preview route in the Worker runtime.
This commit is contained in:
Josh Creek
2026-09-15 17:47:14 +01:00
parent b2b750115f
commit 2766e5ea67
11 changed files with 1629 additions and 39 deletions
+2
View File
@@ -11,3 +11,5 @@ node_modules
pnpm-lock.yaml pnpm-lock.yaml
package-lock.json package-lock.json
yarn.lock yarn.lock
.wrangler/
+17
View File
@@ -144,3 +144,20 @@ jobs:
if-no-files-found: ignore if-no-files-found: ignore
- if: always() - if: always()
run: npx supabase stop run: npx supabase stop
cloudflare-preview-build:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
WRANGLER_SEND_METRICS: 'false'
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run build:cloudflare
- run: npm run check:cloudflare
# This is compilation/package coverage, not a production compatibility gate.
# Native sharp still blocks the share-preview route in the Worker runtime.
+1
View File
@@ -17,3 +17,4 @@ playwright-report
test-results test-results
/static/sprites-grid/ /static/sprites-grid/
.wrangler/
+2 -1
View File
@@ -14,5 +14,6 @@ static/sprites-small/manifest.json
# Machine-local editor and tool settings. # Machine-local editor and tool settings.
**/*.local.json **/*.local.json
# Generated grid artwork. # Generated grid artwork and local Worker runtime output.
static/sprites-grid/ static/sprites-grid/
.wrangler/
+6 -15
View File
@@ -2,20 +2,11 @@ import process from 'node:process';
import AdapterNode from '@sveltejs/adapter-node'; import AdapterNode from '@sveltejs/adapter-node';
import AdapterNetlify from '@sveltejs/adapter-netlify'; import AdapterNetlify from '@sveltejs/adapter-netlify';
export const nodeAdapter = process.env.NODE_ADAPTER === 'true'; export const nodeAdapter =
process.env.NODE_ADAPTER === 'true' || process.env.DEPLOY_TARGET === 'node';
// Netlify is the deployment target; the node adapter exists so the service worker export const cloudflareAdapter = process.env.DEPLOY_TARGET === 'cloudflare';
// build tests can check the `build/client` layout a Node server produces, and so Lighthouse CI
// can audit a production build. Netlify's CDN compresses responses, so precompress here to match.
export const adapter = nodeAdapter export const adapter = nodeAdapter
? AdapterNode({ precompress: true }) ? AdapterNode({ precompress: true })
: AdapterNetlify({ : cloudflareAdapter
// if true, will create a Netlify Edge Function rather ? (await import('@sveltejs/adapter-cloudflare')).default()
// than using standard Node-based functions : AdapterNetlify({ edge: false, split: false });
edge: false,
// if true, will split your app into multiple functions
// instead of creating a single one for the entire app.
// if `edge` is true, this option cannot be used
split: false
});
+1565 -20
View File
File diff suppressed because it is too large Load Diff
+7 -2
View File
@@ -45,12 +45,16 @@
"migrate:convert-tsv": "node scripts/convert-tsv-to-sql.js", "migrate:convert-tsv": "node scripts/convert-tsv-to-sql.js",
"dev:local": "./scripts/dev-local.sh && npm run dev", "dev:local": "./scripts/dev-local.sh && npm run dev",
"dev:supabase": "supabase start && npm run dev", "dev:supabase": "supabase start && npm run dev",
"sprites:grid": "node scripts/grid-thumbnails.mjs" "sprites:grid": "node scripts/grid-thumbnails.mjs",
"build:cloudflare": "DEPLOY_TARGET=cloudflare npm run build",
"preview:cloudflare": "wrangler dev",
"check:cloudflare": "wrangler deploy --dry-run"
}, },
"devDependencies": { "devDependencies": {
"@lhci/cli": "^0.15.1", "@lhci/cli": "^0.15.1",
"@playwright/test": "1.55.1", "@playwright/test": "1.55.1",
"@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-cloudflare": "7.2.9",
"@sveltejs/adapter-netlify": "^4.1.0", "@sveltejs/adapter-netlify": "^4.1.0",
"@sveltejs/adapter-node": "^2.0.0", "@sveltejs/adapter-node": "^2.0.0",
"@sveltejs/adapter-static": "^3.0.0", "@sveltejs/adapter-static": "^3.0.0",
@@ -78,7 +82,8 @@
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"tslib": "^2.6.2", "tslib": "^2.6.2",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"vitest": "^1.0.4" "vitest": "^1.0.4",
"wrangler": "4.131.2"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
+4
View File
@@ -0,0 +1,4 @@
/** Cloudflare performs transport compression; preserve the streaming Response body. */
export function compressResponse(_request: Request, response: Response): Response {
return response;
}
+1 -1
View File
@@ -10,7 +10,7 @@ const config = {
preprocess: vitePreprocess(), preprocess: vitePreprocess(),
kit: { kit: {
// Netlify by default, or the node adapter when NODE_ADAPTER=true. See adapter.mjs. // Netlify by default; DEPLOY_TARGET selects the Cloudflare preview or Node test build.
adapter, adapter,
serviceWorker: { serviceWorker: {
// VitePWA owns registration. Registering here as well requests SvelteKit's default // VitePWA owns registration. Registering here as well requests SvelteKit's default
+11
View File
@@ -1,10 +1,21 @@
import { sveltekit } from '@sveltejs/kit/vite'; import { sveltekit } from '@sveltejs/kit/vite';
import { fileURLToPath } from 'node:url';
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import { SvelteKitPWA } from '@vite-pwa/sveltekit'; import { SvelteKitPWA } from '@vite-pwa/sveltekit';
// you don't need to do this if you're using generateSW strategy in your app // you don't need to do this if you're using generateSW strategy in your app
import { generateSW } from './pwa.mjs'; import { generateSW } from './pwa.mjs';
export default defineConfig({ export default defineConfig({
resolve: {
alias:
process.env.DEPLOY_TARGET === 'cloudflare'
? {
'$lib/server/compression': fileURLToPath(
new URL('./src/lib/server/compression.cloudflare.ts', import.meta.url)
)
}
: {}
},
plugins: [ plugins: [
sveltekit(), sveltekit(),
SvelteKitPWA({ SvelteKitPWA({
+13
View File
@@ -0,0 +1,13 @@
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "livingdextracker-preview",
"main": ".svelte-kit/cloudflare/_worker.js",
"compatibility_date": "2026-09-15",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": ".svelte-kit/cloudflare",
"binding": "ASSETS"
},
"observability": { "enabled": true },
"vars": { "POKEDEX_PERFORMANCE": "true" }
}