Skip to content

fix(core): hide node:async_hooks import from non-Qwik bundlers#8602

Draft
maiieul wants to merge 1 commit intoQwikDev:build/v2from
maiieul:fix-core-locale-node-builtin-import
Draft

fix(core): hide node:async_hooks import from non-Qwik bundlers#8602
maiieul wants to merge 1 commit intoQwikDev:build/v2from
maiieul:fix-core-locale-node-builtin-import

Conversation

@maiieul
Copy link
Copy Markdown
Member

@maiieul maiieul commented May 1, 2026

What is it?

  • Bug

Description

`packages/qwik/src/core/use/use-locale.ts` does `import('node:async_hooks')` inside an `if (isServer)` branch (added in #9116 — `bdc690ddf` feat(core): use AsyncLocalStorage for locale) to set up `AsyncLocalStorage` server-side.

The `isServer` flag is a runtime check (`!isBrowser` from `@qwik.dev/core/build`), not a bundler define. Consumers bundling `@qwik.dev/core` for the browser without the Qwik Vite plugin can't tree-shake this branch and fail at build time:

```
Module build failed: UnhandledSchemeError: Reading from "node:async_hooks" is not handled by plugins (Unhandled scheme).
```

I hit this with Cypress's default webpack-preprocessor in a Qwik 2 monorepo migration. Any spec file whose import graph touches `@qwik.dev/core` blows up. Same class of issue would hit raw webpack/esbuild/Parcel setups that don't run the Qwik optimizer.

Fix

  • Build the dynamic-import target at runtime via `['node', 'async_hooks'].join(':')` so Rollup's constant folding doesn't restore the `node:` literal in the published `core.mjs` (currently it's preserved as-is because `node:async_hooks` is in the rollup externals — see scripts/submodule-core.ts:42).
  • Add `/* webpackIgnore: true /` and `/ @vite-ignore */` magic comments so consumer bundlers leave the dynamic import alone. The `if (isServer)` guard ensures the runtime call only happens in Node, where `node:async_hooks` resolves; the existing `.catch()` already swallows resolution failures elsewhere.
  • Public API unchanged.

use-locale.ts does import('node:async_hooks') inside an if (isServer)
branch to set up AsyncLocalStorage. Consumers that bundle @qwik.dev/core
for the browser without the Qwik Vite plugin (e.g. Cypress's
webpack-preprocessor) can't tree-shake the dead branch and fail at build
time with UnhandledSchemeError.

Build the dynamic-import target at runtime so the literal isn't
preserved through Rollup's constant folding, and add /* webpackIgnore */
+ /* @vite-ignore */ comments to cover consumer bundlers.
@maiieul maiieul requested a review from a team as a code owner May 1, 2026 18:20
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 1, 2026

🦋 Changeset detected

Latest commit: 8302adc

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

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

@maiieul maiieul self-assigned this May 1, 2026
@maiieul maiieul moved this to Waiting For Review in Qwik Development May 1, 2026
@maiieul maiieul marked this pull request as draft May 1, 2026 18:23
@maiieul maiieul moved this from Waiting For Review to In progress in Qwik Development May 1, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 1, 2026

Open in StackBlitz

@qwik.dev/core

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/core@8602

@qwik.dev/router

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/router@8602

eslint-plugin-qwik

npm i https://pkg.pr.new/QwikDev/qwik/eslint-plugin-qwik@8602

create-qwik

npm i https://pkg.pr.new/QwikDev/qwik/create-qwik@8602

@qwik.dev/optimizer

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/optimizer@8602

commit: 8302adc

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
qwik-docs ✅ Ready (View Log) Visit Preview 8302adc

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

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

1 participant