Skip to content

fix(node): suppress JSDOM CSS parse errors during story collection#836

Open
50rayn wants to merge 1 commit into
histoire-dev:mainfrom
50rayn:fix/jsdom-css-noise
Open

fix(node): suppress JSDOM CSS parse errors during story collection#836
50rayn wants to merge 1 commit into
histoire-dev:mainfrom
50rayn:fix/jsdom-css-noise

Conversation

@50rayn

@50rayn 50rayn commented May 1, 2026

Copy link
Copy Markdown
Contributor

Closes #501. Plausibly closes #557 and #466 (same root cause).

JSDOM's CSS parser doesn't understand Tailwind directives (@tailwind, @apply, @theme), CSS container queries, modern selectors, etc. When story collection mounts user stylesheets via setup files, JSDOM emits a jsdomError of type 'css-parsing' whose payload includes the entire stylesheet — extremely noisy and not actionable, since stories don't rely on rendered styles during collection.

VirtualConsole.forwardTo() defaults to forwarding every jsdomError to console.error, hence the spam.

This change disables blanket forwarding ({ jsdomErrors: 'none' }) and re-attaches a manual listener that drops css-parsing and forwards everything else, mirroring jsdom's default behavior for unhandled-exception and other types.

Test plan

  • New unit tests in packages/histoire/src/node/__tests__/dom-env.spec.ts:
    • Stylesheet with Tailwind-style unparseable directives → 0 console.error calls
    • <script> that throws → console.error IS called with the stack
  • pnpm test passes (9/9)
  • Build and lint pass

@bolt-new-by-stackblitz

Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@netlify

netlify Bot commented May 1, 2026

Copy link
Copy Markdown

Deploy Preview for histoire-examples-svelte3 ready!

Name Link
🔨 Latest commit 6e8897f
🔍 Latest deploy log https://app.netlify.com/projects/histoire-examples-svelte3/deploys/69f50a6ff7e3b400084a3ccc
😎 Deploy Preview https://deploy-preview-836--histoire-examples-svelte3.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented May 1, 2026

Copy link
Copy Markdown

Deploy Preview for histoire-site ready!

Name Link
🔨 Latest commit 6e8897f
🔍 Latest deploy log https://app.netlify.com/projects/histoire-site/deploys/69f50a6f908a34000886ca55
😎 Deploy Preview https://deploy-preview-836--histoire-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented May 1, 2026

Copy link
Copy Markdown

Deploy Preview for histoire-controls ready!

Name Link
🔨 Latest commit 6e8897f
🔍 Latest deploy log https://app.netlify.com/projects/histoire-controls/deploys/69f50a6fbe87a50007520eea
😎 Deploy Preview https://deploy-preview-836--histoire-controls.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented May 1, 2026

Copy link
Copy Markdown

Deploy Preview for histoire-examples-vue3 ready!

Name Link
🔨 Latest commit 6e8897f
🔍 Latest deploy log https://app.netlify.com/projects/histoire-examples-vue3/deploys/69f50a6f1e86260008143a96
😎 Deploy Preview https://deploy-preview-836--histoire-examples-vue3.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a custom JSDOM virtual console to suppress CSS parsing errors triggered by Tailwind directives, which previously cluttered the output. It also adds unit tests to verify this behavior and ensure that unhandled script exceptions are still correctly reported. Feedback suggests that the error handler should be updated to use the detail property instead of cause to properly capture stack traces and provide better context for non-CSS errors, matching JSDOM's standard logging behavior.

Comment on lines +17 to +25
virtualConsole.on('jsdomError', (err: Error & { type?: string, cause?: { stack?: string } }) => {
if (err.type === JSDOM_ERROR_CSS_PARSING) return
if (err.type === JSDOM_ERROR_UNHANDLED_EXCEPTION) {
globalThis.console.error(err.cause?.stack ?? err.message)
}
else {
globalThis.console.error(err.message)
}
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The manual jsdomError handler does not fully mirror JSDOM's default forwardTo behavior, which may lead to missing information in logs.

  1. JSDOM uses the detail property (not cause) to store the original error object for unhandled-exception. Using cause will likely result in undefined in most JSDOM versions, causing the stack trace to be lost.
  2. For other error types, JSDOM's default behavior is to log both the message and the detail object (e.g., console.error(message, detail)). The current implementation only logs the message, which might omit crucial context for errors like resource loading failures.

Updating the handler to use detail and include it in the output will better align with JSDOM's standard error reporting.

Suggested change
virtualConsole.on('jsdomError', (err: Error & { type?: string, cause?: { stack?: string } }) => {
if (err.type === JSDOM_ERROR_CSS_PARSING) return
if (err.type === JSDOM_ERROR_UNHANDLED_EXCEPTION) {
globalThis.console.error(err.cause?.stack ?? err.message)
}
else {
globalThis.console.error(err.message)
}
})
virtualConsole.on('jsdomError', (err: Error & { type?: string, detail?: any }) => {
if (err.type === JSDOM_ERROR_CSS_PARSING) return
if (err.type === JSDOM_ERROR_UNHANDLED_EXCEPTION) {
globalThis.console.error(err.detail?.stack ?? err.detail?.message ?? err.message)
}
else {
globalThis.console.error(err.message, err.detail)
}
})

@pkg-pr-new

pkg-pr-new Bot commented May 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

histoire

npm i https://pkg.pr.new/histoire@836

@histoire/app

npm i https://pkg.pr.new/@histoire/app@836

@histoire/controls

npm i https://pkg.pr.new/@histoire/controls@836

@histoire/plugin-nuxt

npm i https://pkg.pr.new/@histoire/plugin-nuxt@836

@histoire/plugin-percy

npm i https://pkg.pr.new/@histoire/plugin-percy@836

@histoire/plugin-screenshot

npm i https://pkg.pr.new/@histoire/plugin-screenshot@836

@histoire/plugin-svelte

npm i https://pkg.pr.new/@histoire/plugin-svelte@836

@histoire/plugin-vue

npm i https://pkg.pr.new/@histoire/plugin-vue@836

@histoire/shared

npm i https://pkg.pr.new/@histoire/shared@836

@histoire/vendors

npm i https://pkg.pr.new/@histoire/vendors@836

commit: 6e8897f

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.

Error: Could not parse CSS stylesheet TailwindCSS Logs spam the console

1 participant