fix(devframe): split tsdown into client + server configs to keep node:* out of browser#17
Merged
Merged
Conversation
…:* out of browser
A single combined build lets rolldown hoist shared helpers into chunks
reachable from both server-only entries (e.g. ws-server, h3, node:crypto)
and the agnostic/client outputs, leaking node-only imports into
browser-loadable files like utils/hash.mjs and client/index.mjs. The
previous `ohash/crypto` alias only addressed one symptom; the underlying
chunk-graph mixing remained.
Split packages/devframe/tsdown.config.ts into defineConfig([client, server])
so each platform owns its chunk graph. Client config uses platform: 'browser'
(drops the ohash/crypto alias), forces .mjs / .d.mts extensions to preserve
the package.json exports map, and gates the build via a build:done hook
calling scripts/check-client-dist.ts. The check BFS-walks chunks reachable
from each agnostic entry and fails on forbidden static imports (ws, h3,
node:*, devframe/{rpc/transports,node,adapters,helpers,recipes}/*, and the
server-only utils launch-editor/open/serve-static). Snapshot regenerated for
rpc/transports/ws-client where the smaller per-config DTS chunk graph now
inlines WsRpcChannelOptions + createWsRpcChannel locally instead of
re-exporting from a shared chunk (same public API).
Mirrors vitejs/devtools#347.
✅ Deploy Preview for devfra ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR splits the devframe package build into browser/client and node/server tsdown configs to prevent server-only imports from leaking into browser-loadable dist files, and adds a dist scanner to enforce that boundary.
Changes:
- Splits
packages/devframe/tsdown.config.tsinto separate browser and node configs with shared dependency bundling rules. - Adds
check-client-dist.tsto scan reachable client chunks for forbidden server-only imports. - Updates the
ws-clienttsnapi snapshot to reflect the new generated DTS shape.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
packages/devframe/tsdown.config.ts |
Defines separate client/server build configs and wires the client dist guard. |
packages/devframe/scripts/check-client-dist.ts |
Adds a build-time scanner for forbidden imports in reachable client chunks. |
tests/__snapshots__/tsnapi/devframe/rpc/transports/ws-client.snapshot.d.ts |
Updates API snapshot output for the ws-client transport. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+89
to
+92
| hooks: { | ||
| 'build:done': async () => { | ||
| const { checkClientDist } = await import('./scripts/check-client-dist.ts') | ||
| await checkClientDist({ |
Comment on lines
+122
to
+126
| 'rpc/index': 'src/rpc/index.ts', | ||
| 'rpc/client': 'src/rpc/client.ts', | ||
| 'rpc/server': 'src/rpc/server.ts', | ||
| 'rpc/transports/ws-client': 'src/rpc/transports/ws-client.ts', | ||
| 'rpc/transports/ws-server': 'src/rpc/transports/ws-server.ts', |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
packages/devframe/tsdown.config.tsintodefineConfig([client, server])so each platform owns its own rolldown chunk graph — previously a single combined build could hoist shared helpers into chunks reachable from both server-only entries (ws-server, h3, node:crypto) and the agnostic/client outputs, leaking node imports into browser-loadable files likeutils/hash.mjs. Client config usesplatform: 'browser'(drops theohash/cryptoalias workaround) with.mjs/.d.mtsextensions forced to preserve the package.jsonexportsmap; server config keepsplatform: 'node'.packages/devframe/scripts/check-client-dist.ts, wired viabuild:doneon the client config: BFS-walks every chunk reachable from the 11 agnostic entries (following static + dynamic imports) and fails the build on any forbidden static import —ws,h3,node:*,devframe/{rpc/transports,node,adapters,helpers,recipes}/*, and the server-onlydevframe/utils/{launch-editor,open,serve-static}.rpc/transports/ws-clienttsnapi snapshot: same public API, but the smaller per-config DTS chunk graph now inlinesWsRpcChannelOptions+createWsRpcChannellocally instead of re-exporting them from a shared chunk. Mirrors fix(core): split client/server tsdown builds to keep ws/node out of browser vitejs/devtools#347.Test plan
pnpm --filter devframe build—[check-client-dist] OK — scanned 14 chunks reachable from 11 client entriespnpm test— 317/317pnpm typecheck,pnpm lintcleanimport 'node:fs'added tosrc/utils/colors.ts→ guard fails with the expected violation; reverted