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

fix: prevent vitest from hanging when using cloudflare/cloudflare-workers #12306

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
5 changes: 5 additions & 0 deletions .changeset/tidy-drinks-melt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@sveltejs/kit": patch
---

fix: prevent vitest from hanging when using cloudflare/cloudflare-workers adapter
3 changes: 1 addition & 2 deletions packages/kit/src/core/postbuild/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ async function prerender({ out, manifest_path, metadata, verbose, env }) {
/** @type {import('types').ValidatedKitConfig} */
const config = (await load_config()).kit;

const emulator = await config.adapter?.emulate?.();

/** @type {import('types').Logger} */
const log = logger({ verbose });

Expand Down Expand Up @@ -205,6 +203,7 @@ async function prerender({ out, manifest_path, metadata, verbose, env }) {
/** @type {Map<string, import('types').PrerenderDependency>} */
const dependencies = new Map();

const emulator = await config.adapter?.emulate?.();
const response = await server.respond(new Request(config.prerender.origin + encoded), {
getClientAddress() {
throw new Error('Cannot read clientAddress during prerendering');
Expand Down
6 changes: 3 additions & 3 deletions packages/kit/src/exports/vite/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ const cwd = process.cwd();
* @param {import('vite').ViteDevServer} vite
* @param {import('vite').ResolvedConfig} vite_config
* @param {import('types').ValidatedConfig} svelte_config
* @return {Promise<Promise<() => void>>}
* @return {() => void}
*/
export async function dev(vite, vite_config, svelte_config) {
export function dev(vite, vite_config, svelte_config) {
installPolyfills();

const async_local_storage = new AsyncLocalStorage();
Expand Down Expand Up @@ -419,7 +419,6 @@ export async function dev(vite, vite_config, svelte_config) {
});

const env = loadEnv(vite_config.mode, svelte_config.kit.env.dir, '');
const emulator = await svelte_config.kit.adapter?.emulate?.();

return () => {
const serve_static_middleware = vite.middlewares.stack.find(
Expand Down Expand Up @@ -521,6 +520,7 @@ export async function dev(vite, vite_config, svelte_config) {
return;
}

const emulator = await svelte_config.kit.adapter?.emulate?.();
const rendered = await server.respond(request, {
getClientAddress: () => {
const { remoteAddress } = req.socket;
Expand Down
4 changes: 2 additions & 2 deletions packages/kit/src/exports/vite/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,8 +669,8 @@ async function kit({ svelte_config }) {
* Adds the SvelteKit middleware to do SSR in dev mode.
* @see https://vitejs.dev/guide/api-plugin.html#configureserver
*/
async configureServer(vite) {
return await dev(vite, vite_config, svelte_config);
configureServer(vite) {
return dev(vite, vite_config, svelte_config);
},

/**
Expand Down
3 changes: 1 addition & 2 deletions packages/kit/src/exports/vite/preview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export async function preview(vite, vite_config, svelte_config) {
read: (file) => createReadableStream(`${dir}/${file}`)
});

const emulator = await svelte_config.kit.adapter?.emulate?.();

return () => {
// Remove the base middleware. It screws with the URL.
// It also only lets through requests beginning with the base path, so that requests beginning
Expand Down Expand Up @@ -185,6 +183,7 @@ export async function preview(vite, vite_config, svelte_config) {
request: req
});

const emulator = await svelte_config.kit.adapter?.emulate?.();
setResponse(
res,
await server.respond(request, {
Expand Down
1 change: 1 addition & 0 deletions packages/kit/test/apps/cloudflare/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.wrangler
1 change: 1 addition & 0 deletions packages/kit/test/apps/cloudflare/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict=true
19 changes: 19 additions & 0 deletions packages/kit/test/apps/cloudflare/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}
30 changes: 30 additions & 0 deletions packages/kit/test/apps/cloudflare/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "cloudflare",
"version": "0.0.1",
"scripts": {
"dev": "vite dev",
"prebuild": "pnpm run --filter @sveltejs/adapter-cloudflare build",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
"pretest:integration": "pnpm run --filter @sveltejs/adapter-cloudflare build",
"test": "npm run test:integration && npm run test:unit",
"test:integration": "playwright test",
"test:unit": "vitest"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20231121.0",
"@playwright/test": "^1.28.1",
"@sveltejs/adapter-cloudflare": "workspace:^",
"@sveltejs/kit": "workspace:^",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"typescript": "^5.0.0",
"vite": "^5.0.3",
"vitest": "^1.2.0",
"wrangler": "^3.59.0"
},
"type": "module"
}
11 changes: 11 additions & 0 deletions packages/kit/test/apps/cloudflare/playwright.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** @type {import('@playwright/test').PlaywrightTestConfig} */
const config = {
webServer: {
command: 'npm run build && npm run preview',
port: 4173
},
testDir: 'tests',
testMatch: /(.+\.)?(test|spec)\.[jt]s/
};

export default config;
19 changes: 19 additions & 0 deletions packages/kit/test/apps/cloudflare/src/app.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { KVNamespace } from '@cloudflare/workers-types';

// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
interface Platform {
env: {
TEST_NAMESPACE: KVNamespace;
};
}
}
}

export {};
12 changes: 12 additions & 0 deletions packages/kit/test/apps/cloudflare/src/app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
5 changes: 5 additions & 0 deletions packages/kit/test/apps/cloudflare/src/lib/vitest.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { test } from 'vitest';

// This ensures `vitest` runs without hanging indefinitely
// See https://github.com/sveltejs/kit/issues/12305 for details
test('vitest does not hang', () => {});
8 changes: 8 additions & 0 deletions packages/kit/test/apps/cloudflare/src/routes/+page.server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('./$types').PageServerLoad} */
export async function load({ platform }) {
const test_namespace =
/** @type {import('@cloudflare/workers-types').KVNamespace} */ platform?.env.TEST_NAMESPACE;
await test_namespace?.put('foo', 'bar');
const value = await test_namespace?.get('foo');
return { value };
}
24 changes: 24 additions & 0 deletions packages/kit/test/apps/cloudflare/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script>
/** @type {import('./$types').PageServerData} */
export let data;
</script>

<svelte:head>
<title>Home</title>
<meta name="description" content="Svelte demo app" />
</svelte:head>

<section>
<h1>Cloudflare Adapter Demo</h1>
<span class="value">value: {JSON.stringify(data.value)}</span>
</section>

<style>
section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex: 0.6;
}
</style>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/kit/test/apps/cloudflare/static/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
15 changes: 15 additions & 0 deletions packages/kit/test/apps/cloudflare/svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import adapter from '@sveltejs/adapter-cloudflare';

/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter({
routes: {
include: ['/*'],
exclude: ['<all>']
}
})
}
};

export default config;
6 changes: 6 additions & 0 deletions packages/kit/test/apps/cloudflare/tests/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { expect, test } from '@playwright/test';

test('value from KV is as inserted from server', async ({ page }) => {
await page.goto('/');
await expect(page.locator('span.value')).toHaveText('value: "bar"');
});
15 changes: 15 additions & 0 deletions packages/kit/test/apps/cloudflare/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as path from 'node:path';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';

export default defineConfig({
plugins: [sveltekit()],
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
},
server: {
fs: {
allow: [path.resolve('../../../src')]
}
}
});
5 changes: 5 additions & 0 deletions packages/kit/test/apps/cloudflare/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name = "svelte-cloudflare-test"

kv_namespaces = [
{ binding = "TEST_NAMESPACE", id = "c9f87d3580e24ccc8743d6c8c0d1428c" }
]
Loading
Loading