Skip to content

feat: warn at build time when the server build targets a worker runtime (ssr.target webworker) - #373

Merged
ryansolid merged 1 commit into
nextfrom
feat/webworker-async-hooks-warning
Sep 27, 2026
Merged

ryansolid merged 1 commit into
nextfrom
feat/webworker-async-hooks-warning

Conversation

@ryansolid

Copy link
Copy Markdown
Member

What

Emit a build-time warning when the server build targets a worker runtime (ssr.target: 'webworker') and the plugin generates server code — SSR or client start mode, or serverFunctions on its own.

Why

Follow-up promised in solidjs/solid#3597 (the maintainer's comment). The generated server code — the start-mode handler (src/ssr/index.ts) and the server-function handler module (src/server-functions/index.ts) — imports @solidjs/web/storage, the one Solid module that needs node:async_hooks (AsyncLocalStorage keeps the request event live across awaits; there is no sync-scope fallback). On a worker runtime without Node compat that failed at deploy with a bare No such module "node:async_hooks". Shopify Oxygen's Vite plugin (@shopify/mini-oxygen) sets ssr.target: 'webworker', so the target is the signal; the reporter verified Oxygen works with a compatibility_date ≥ 2026-08-04 and asked that the warning mention both that route and the nodejs_compat flag.

How

  • Detection in the main plugin's configResolved (src/index.ts): command === 'build' and (start or serverFunctions set) and resolved config.ssr.target === 'webworker' — the same property Vite itself reads for the ssr environment.
  • Emission from the plugin's buildStart when this.environment.name === 'ssr', through config.logger.warn like the plugin's other config-level warnings. This is what makes it fire exactly once per build: Vite's default builder (sharedConfigBuild: false) resolves the config once for the builder and once per environment, so a configResolved-time warning printed three times per vite build (verified before moving it). It does not fire for the client build, and never in dev (the ssr environment runs in Node there). Works for a full vite build (builder), vite build --ssr, and host orchestrators that build the ssr environment themselves.
  • A transform-only ssr: true config (no generated server code) stays silent; whether the user's own server imports @solidjs/web/storage is theirs to know.

Warning text

[@solidjs/vite-plugin] The server build targets a worker runtime (ssr.target = "webworker"). Solid's server runtime requires Node's async context (node:async_hooks / AsyncLocalStorage). On Cloudflare Workers and compatible runtimes (e.g. Shopify Oxygen) set a compatibility_date of 2026-08-04 or later (nodejs_compat is on by default from that date), or enable the nodejs_compat flag. See https://github.com/solidjs/solid/issues/3597

Tests

examples/start-ssr/test/webworker-warning.mjs (added to the example's test script, after components-warning.mjs). Real in-process builds, no browser:

  • start-mode build with ssr.target webworker warns exactly once (full buildApp(), client + ssr) + text assertions: names ssr.target = "webworker", node:async_hooks / AsyncLocalStorage, the compatibility_date route (2026-08-04), the nodejs_compat flag route, Shopify Oxygen, and links [2.0 rc.9] Start mode server handler requires node:async_hooks, fails on Workers runtimes without Node compat solid#3597
  • start-mode build with the node target does not warn
  • client start mode with serverFunctions and webworker target warns once
  • serverFunctions-only ssr build with webworker target warns once
  • transform-only ssr build with webworker target does not warn
  • vite dev with ssr.target webworker does not warn

Also ran locally: pnpm build, the full examples/start-ssr suite (run.mjs 600/600, http-bridge.mjs, components-warning.mjs), prettier on the touched files.

Public API changes

None. No new option or config surface; the condition is the resolved ssr.target.

Notes for review

  • Scope: the brief for this follow-up talked about start mode; the gate also covers serverFunctions without start, because that path's handler module carries the same @solidjs/web/storage import and fails identically on a worker without Node compat. Easy to narrow to start only if preferred.
  • Changeset is patch, matching the vast majority of changesets on next.

Refs solidjs/solid#3597

— Claude via Cursor

The generated server code (the start-mode handler and the server-function
handler module) imports `@solidjs/web/storage`, the one Solid module that
needs `node:async_hooks`. A build with `ssr.target: 'webworker'` (what
Shopify Oxygen's Vite plugin sets) only failed at deploy with a bare
`No such module "node:async_hooks"` (solidjs/solid#3597). Name the
requirement and both fixes at build time instead: a compatibility_date of
2026-08-04 or later, or the nodejs_compat flag.

Detected in configResolved (build + start or serverFunctions + webworker
target), emitted from the ssr environment's buildStart so it lands exactly
once per server build — the default builder resolves the config once per
environment on top of its own pass, so a configResolved warning printed
three times. Never in dev, where the ssr environment runs in Node.

Co-authored-by: Claude via Cursor <noreply@cursor.com>
@changeset-bot

changeset-bot Bot commented Sep 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: de42b22

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@solidjs/vite-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Sep 27, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@solidjs/vite-plugin@373

commit: de42b22

@ryansolid
ryansolid merged commit 08782f2 into next Sep 27, 2026
6 checks passed
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.

1 participant