Skip to content

feat(cloudflare/Worker): Add option (bundle:false) to skip bundling by Rolldown#117

Open
czxtm wants to merge 6 commits into
alchemy-run:mainfrom
czxtm:main
Open

feat(cloudflare/Worker): Add option (bundle:false) to skip bundling by Rolldown#117
czxtm wants to merge 6 commits into
alchemy-run:mainfrom
czxtm:main

Conversation

@czxtm
Copy link
Copy Markdown
Contributor

@czxtm czxtm commented Apr 30, 2026

I discovered this when trying to deploy Fumadocs. This PR unblocks the ability to deploy Fumadocs and probably many other Next.js apps using @opennextjs/cloudflare:

When deploying a Worker whose main already points at a complete, runtime-ready ESM bundle produced by an external tool (OpenNext, wrangler, custom build pipelines, etc.), alchemy still runs that artifact through cloudflareRolldown.

isExternal: true already disables alchemy's Effect-wrapping virtual entry, but prepareBundle still calls Bundle.build(...) with cloudflareRolldown on the way through. There is currently no way to opt out of that re-bundle.

This adds a new WorkerProps.bundle?: boolean (default true). When set to false, prepareBundle reads props.main directly and returns a synthetic single-file Bundle.BundleOutput whose content is the file's bytes verbatim and whose hash is sha256(bytes). The downstream upload path is unchanged.

The accompanying integration test works as follows:

  1. Deploy a hand-written ESM bundle that contains a SENTINEL comment
  2. Verify the resulting worker.hash?.bundle equals sha256(sourceBytes) (which is impossible to satisfy if rolldown ran on the file)
  3. Round-trip a request through the deployed Worker to confirm the literal sentinel string survives.

A reproduction of a failing deploy of Fumadocs (using bunx create-fumadocs-app) is available here: https://github.com/czxtm/repro-alchemy-bundle-false

The main branch is a failing reproduction while the fix-bundle-false branch contains a patched version of alchemy that includes the changes introduced in this PR.

If isExternal: true is actually supposed to skip the re-bundling as well and just needs a bugfix, then this PR is not the right solution and can be closed.

…r-byte

When deploying a Worker whose `main` already points at a complete,
runtime-ready ESM bundle produced by an external tool (OpenNext,
wrangler, custom build pipelines, etc.), alchemy still runs that
artifact through `cloudflareRolldown`.

`isExternal: true` already disables alchemy's Effect-wrapping virtual
entry, but `prepareBundle` still calls `Bundle.build(...)` with
`cloudflareRolldown` on the way through. There is currently no way to
opt out of that re-bundle.

This adds a new `WorkerProps.bundle?: boolean` (default `true`). When
set to `false`, `prepareBundle` reads `props.main` directly and returns
a synthetic single-file `Bundle.BundleOutput` whose `content` is the
file's bytes verbatim and whose `hash` is sha256(bytes). The downstream
upload path is unchanged.

The accompanying integration test works as follows:

1. Deploy a hand-written ESM bundle that contains a SENTINEL comment
2. Verify the resulting `worker.hash?.bundle` equals `sha256(sourceBytes)` (which is
   impossible to satisfy if rolldown ran on the file)
3. Round-trip a request through the deployed Worker to confirm the literal sentinel
   string survives.
@sam-goodwin
Copy link
Copy Markdown
Contributor

cc @john-royal

@sam-goodwin
Copy link
Copy Markdown
Contributor

If isExternal: true is actually supposed to skip the re-bundling as well and just needs a bugfix, then this PR is not the right solution and can be closed.

isExternal is Effect vs Async style. It should not skip bundling

@sam-goodwin
Copy link
Copy Markdown
Contributor

Can we add an example that exercises this code path? Maybe examples/cloudflare-nextjs, is that what you're doing?

@czxtm
Copy link
Copy Markdown
Contributor Author

czxtm commented May 1, 2026

Yeah, I'll move the one in the repro to examples

czxtm and others added 2 commits May 1, 2026 04:14
Minimal Next.js + OpenNext app deployed via `Cloudflare.Worker` with
`bundle: false`, demonstrating the new opt-out for alchemy's rolldown
step on pre-built worker bundles. Condensed from the upstream repro
(czxtm/repro-alchemy-bundle-false) — 11 files instead of ~36, no
Fumadocs/MDX/AI/Tailwind scaffolding.
@czxtm
Copy link
Copy Markdown
Contributor Author

czxtm commented May 12, 2026

@sam-goodwin is this still useful?

@sam-goodwin
Copy link
Copy Markdown
Contributor

@sam-goodwin is this still useful?

@john-royal can you look at this and decide what we should do here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants