fix: workerd bundling — cache.js lazy import("bun") stays non-literal in dist - #148
Conversation
There was a problem hiding this comment.
Pull request overview
Prevents Workers bundlers from statically resolving Bun’s Redis client import.
Changes:
- Hides the Bun import specifier behind a
Map. - Adds a packed-dist regression check.
- Adds a patch changeset.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
packages/core/src/cache.ts |
Makes the Bun import non-analyzable. |
scripts/smoke-packed.sh |
Checks packed output for literal Bun imports. |
.changeset/cache-bun-import.md |
Documents the bundling fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # source guards this with a data-indirected specifier; assert tsdown didn't | ||
| # constant-fold it back (it folded a plain `const s = "bun"; import(s)` once). | ||
| echo "→ verifying the packed core dist carries no literal runtime-only imports" | ||
| core_dist=$(tar -xzOf "$work"/junejs-core-*.tgz package/dist/cache.js) || { |
There was a problem hiding this comment.
Already addressed in f8f43fa (fix(smoke): build core before inspecting its packed dist) — the guard now runs bun run build in packages/core and REPACKS it before the extraction, mirroring publish.yml's pre-pack build, so the inspected tarball is the artifact npm consumers actually get. Empirically green: the packed job passed on this branch after that commit (32s), and the full local run passes end-to-end. The review snapshot predates the fix commit.
…ist (#141) tsdown/rolldown constant-folded the plain-const guard back into a literal import("bun") in dist/cache.js, and cache.ts is in core's root import graph — every Workers consumer's bundler (wrangler/esbuild) then failed with 'Could not resolve "bun"' even though the redis path never executes there. The specifier now lives in data (a Map lookup no bundler evaluates); smoke-packed.sh asserts the packed dist stays fold-free (the same guard survived in agent-models and folded here — inlining is heuristic, so the invariant is asserted, not assumed). Verified: the original repro (wrangler deploy --dry-run on examples/agent-edge) bundles clean.
The smoke tarballs are packed without dist (publish.yml builds before packing), so the new fold-guard read a file that never exists in the smoke flow. Build + repack core first — the same pre-pack step publish runs — so the inspected artifact is the one npm consumers actually get.
ddf6698 to
f8f43fa
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (1)
scripts/smoke-packed.sh:65
- The guard only matches the exact spelling
import("bun")/import('bun'). A still-static literal such asimport( "bun")(valid output after a formatter change) passes this check even though wrangler will resolve it and fail. Allow whitespace around the call delimiter so the assertion covers literal imports rather than one serialization.
if printf '%s' "$core_dist" | grep -qE 'import\((["'\''])bun'; then
Closes #141.
The source already guarded the Bun-only redis path with a non-literal specifier, but tsdown/rolldown constant-folds
const s = "bun"; import(s)back into a literalimport("bun")indist/cache.js— andcache.tssits in @junejs/core's root import graph (agent.ts→cache.ts), so every consumer whose own bundler resolves imports statically (wrangler/esbuild for Workers) failed withCould not resolve "bun", even though the redis path never executes there.Two parts:
Maplookup no bundler evaluates. Rebuilt dist carriesimport(runtimeModules.get("redis")), which esbuild treats as a non-analyzable dynamic import and leaves alone.agent-models.jsand folded incache.js(the optimizer's inlining is heuristic), soscripts/smoke-packed.shnow greps the packed core dist and fails the packed E2E if a literalimport("bun"ever reappears.Verified: the original repro —
bunx wrangler deploy --dry-runonexamples/agent-edge— bundles clean (Total Upload 49.32 KiB) against the rebuilt dist;bun run cigreen (1084 tests / 0 fail); the redis store's own tests unchanged and passing.