sveltejs / sveltejs/kit

adapter-cloudflare on Vite 8 (Rolldown): worker fails to start with createRequire(import.meta.url) when a CJS dep uses a Node builtin

Open
#15,960 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

  • #15627 by @teemingc — closed without merging
pkg:adapter-cloudflare
Dominant language
JavaScript
Stars
20.8k
Forks
2.3k
Avg merge
1d 16h
Merged PRs (30d)
156

Description

Describe the bug

A SvelteKit app using @sveltejs/adapter-cloudflare on Vite 8 (which bundles Rolldown) crashes at Cloudflare Workers (workerd) startup:

Uncaught TypeError: The argument 'path' ... must be a file URL ... Received 'undefined'
  at createRequire (node:module)
[code: 10021] The Workers runtime failed to start.

It reproduces with wrangler deploy and wrangler dev --local. vite dev (Node SSR) and vite build pass — it only fails in real workerd.

Cause: Rolldown emits var __require = createRequire(import.meta.url) eagerly in a shared chunk for CJS interop, and import.meta.url is undefined in workerd. It is triggered by any CommonJS dependency in the SSR graph that uses a Node builtin (e.g. node-forge doing require("crypto")). The shared helper chunk is statically imported by output/server/index.js → the worker entry, so it is on the eager startup path even when the dependency is only used by one route. The old Astro adapter (@astrojs/cloudflare, on Vite 7 / Rollup) statically converts the same require() to an ESM import and does not hit this.

Why this is a SvelteKit-side issue (not just a Vite one): the underlying bundling behaviour is already filed at Vite — vitejs/vite#22618 and PR vitejs/vite#22619 (which restores conversion of bundled CJS builtin require() for ssr.target: 'webworker'). But Vite only applies that path when ssr.target: 'webworker' is set, and @sveltejs/adapter-cloudflare does not set it, so SvelteKit's Cloudflare SSR build uses platform: 'node' and emits the crashing createRequire shim. This issue tracks the adapter-cloudflare side. I'm happy to submit a PR once there's agreement on the approach (and once vitejs/vite#22619 lands).

Reproduction

https://github.com/basuke/sveltekit-adapter-cloudflare-createrequire-repro

(npm install --legacy-peer-deps — @sveltejs/vite-plugin-svelte still declares vite ^6||^7 as a peer — then npm run build && npx wrangler dev --local → code 10021 at startup. .svelte-kit/output/server/chunks/chunk.js contains var __require = createRequire(import.meta.url).)

Logs
service core:user:...: Uncaught TypeError: The argument 'path' must be a file URL object, a file URL string, or an absolute path string. Received 'undefined'
  at node:module:34:15 in createRequire
  at .svelte-kit/output/server/chunks/chunk.js
  ...
The Workers runtime failed to start. [code: 10021]
System Info
System:
  OS: macOS 26.5
  CPU: (20) arm64 Apple M1 Ultra
Binaries:
  Node: 22.21.1
  npm: 11.14.1
Browsers:
  Chrome: 148.0.7778.217
  Safari: 26.5
npmPackages:
  @sveltejs/adapter-cloudflare: ^7.2.8 => 7.2.8
  @sveltejs/kit: ^2.61.1 => 2.63.0
  @sveltejs/vite-plugin-svelte: ^6.2.1 => 6.2.4
  svelte: ^5.43.6 => 5.56.2
  vite: ^8.0.15 => 8.0.16
Severity

blocking an upgrade

Additional Information

Proposed direction (for discussion): once vitejs/vite#22619 lands, adapter-cloudflare (workerd) should build with ssr.target: 'webworker' — matching what @astrojs/cloudflare effectively does. Open questions:

  1. Where should ssr.target: 'webworker' be set? The adapter object exposes no Vite/SSR config hook today; it would likely go in @sveltejs/kit's Vite plugin keyed off the active adapter, or via a new adapter config hook.
  2. Overlap with #15627 (move adapter-cloudflare onto Cloudflare's official Vite plugin)? If that is the intended long-term path, it handles workerd builtins natively and may make ssr.target moot.

Alternatives tried (all insufficient on their own):

  • ssr.target: 'webworker' alone — blocked by the Vite gap (#22619); a bundled CJS dep's require("crypto") becomes a throwing stub and the build fails.
  • ssr.noExternal: true — builds, but crypto resolves to a browser stub missing randomBytes at runtime.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the adapter-cloudflare configuration and SvelteKit’s Vite plugin, then compare the reproduction’s .svelte-kit/output/server/chunks/chunk.js and output/server/index.js with the Vite #22619 behavior. Review the adapter configuration hook questions and the relationship to #15627. Done means the Vite 8 Cloudflare build starts in workerd without the eager createRequire(import.meta.url) failure while preserving CommonJS Node builtin usage.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, vite
Domain
build-system, cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.