You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A side-effect module imported inside both preview.js and a component results in an incorrect bundle being created by storybook build. Specifically, the ordering of these side-effects is important, but the resulting bundle does not preserve this ordering, resulting in an error.
These side-effects execute correctly in storybook dev.
Our design system requires injecting a CSS reset via a side-effect import before using any components. We rely on import order to ensure that any other component-specific CSS is injected after the CSS reset. We enforce this by setting a flag as a side-effect in the CSS reset import, and then checking that flag as a side-effect when our design system's provider is imported.
It looks like this:
// App.tsx// Imports CSS as a side-effect, sets a flagimport'braid-design-system/reset';// Checks the flag set by the above importimport{BraidProvider}from'braid-design-system';
Every component must be wrapped inside our design system's provider in order to function. So naturally preview.js is a logical place to both import our CSS reset and declare a decorator that wraps all stories with a BraidProvider.
Currently we have a webpack-based Storybook that functions correctly with this setup. However, when attempting to migrate to Vite, we found that CSS was being bundled in a different order than declared during storybook build. Specifically, the reset CSS was injected after component-specific CSS, causing styling issues. CSS is in the correct order during storybook dev.
I initially though this somehow being caused by our CSS-in-JS solution Vanilla Extract, but that turned out to be a red herring.
My reproduction has narrowed the bug down to just some simple side-effects. In short: a side-effect shared by both preview.js and a component Button.jsx results in a bundle that does not respect the ordering of these side-effects.
The reproduction is a simplification of our design system's CSS reset functionality. It is implemented as a flag that is set (via side-effect-package/set) and then checked (via side-effect-package/check) within preview.js, and then the component Button.jsx once again checks this flag value.
During storybook dev, these side-effects fire as expected. The flag is set to true, and then checked. During storybook build however, the bundle does not include the code in side-effect-package/set, only side-effect-package/check. This check runs, and it fails because the flag was never set.
It's worth noting that side-effect-package has "sideEffects": true in its package.json, so it should be apparent to any bundler that it contains side-effects.
Another point to note is that the issue only occurs if both preview.js and Button.jsxshare a side-effect import. If you comment out import "side-effect-package/check" and instead uncomment import "side-effect-package/other", all side-effects are bundle correctly and no errors are thrown.
I've tried debugging why this particular bundling quirk is occurring, but I can't quite find the right Rollup plugin hook to give me the information I need. Specifically: why are the side-effects from preview.js not being include in their entirety in the bundle.
This seems like a trivial side-effect issue, but it speaks to a larger discrepancy between vite's dev server and production bundle.
The text was updated successfully, but these errors were encountered:
** Disclaimer** This information might be inaccurate, due to it being generated automatically
This appears to be a Vite bundling issue with side effects in the preview bundle. The fix requires: 1. Modify the Vite builder configuration in code/builders/builder-vite/src/index.ts to ensure side effects from preview.js are properly included: ts // Add to vite config options build: { rollupOptions: { preserveEntrySignatures: 'strict', output: { preserveModules: true, preserveModulesRoot: 'src' } } } 2. Update the preview entry handling in code/builders/builder-vite/src/presets/preview-preset.ts to explicitly mark preview.js imports as side effects: ts plugins: [ { name: 'storybook:preview-side-effects', enforce: 'pre', resolveId(id, importer) { if (id.includes('preview')) { return { id, moduleSideEffects: true }; } } } ] This will ensure Vite properly bundles and orders shared side effects between preview.js and components.
About Greptile
This response provides a starting point for your research, not a precise solution.
Help us improve! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.
As suggested by the bot, setting output: { preserveModules: true } does fix the issue, but at the cost of generating significantly more chunks in the final build. This seems like a blunt hammer solution that doesn't really address the core issue: incorrect treatment of side-effects in preview.js.
The bot's other suggestion, setting moduleSideEffects: true for the preview module in resolveId, breaks the build.
Describe the bug
A side-effect module imported inside both
preview.js
and a component results in an incorrect bundle being created bystorybook build
. Specifically, the ordering of these side-effects is important, but the resulting bundle does not preserve this ordering, resulting in an error.These side-effects execute correctly in
storybook dev
.Reproduction link
https://github.com/askoufis/storybook-sideffect-repro
Reproduction steps
git clone https://github.com/askoufis/storybook-sideffect-repro
cd storybook-sideffect-repro/app
pnpm install
pnpm dev
. TheButton
primary story works as expected.pnpm build && pnpm serve
. Opening storybook results in an error being thrown.System
Additional context
Our design system requires injecting a CSS reset via a side-effect import before using any components. We rely on import order to ensure that any other component-specific CSS is injected after the CSS reset. We enforce this by setting a flag as a side-effect in the CSS reset import, and then checking that flag as a side-effect when our design system's provider is imported.
It looks like this:
Every component must be wrapped inside our design system's provider in order to function. So naturally
preview.js
is a logical place to both import our CSS reset and declare a decorator that wraps all stories with aBraidProvider
.Currently we have a webpack-based Storybook that functions correctly with this setup. However, when attempting to migrate to Vite, we found that CSS was being bundled in a different order than declared during
storybook build
. Specifically, the reset CSS was injected after component-specific CSS, causing styling issues. CSS is in the correct order duringstorybook dev
.I initially though this somehow being caused by our CSS-in-JS solution Vanilla Extract, but that turned out to be a red herring.
My reproduction has narrowed the bug down to just some simple side-effects. In short: a side-effect shared by both
preview.js
and a componentButton.jsx
results in a bundle that does not respect the ordering of these side-effects.The reproduction is a simplification of our design system's CSS reset functionality. It is implemented as a flag that is set (via
side-effect-package/set
) and then checked (viaside-effect-package/check
) withinpreview.js
, and then the componentButton.jsx
once again checks this flag value.During
storybook dev
, these side-effects fire as expected. The flag is set totrue
, and then checked. Duringstorybook build
however, the bundle does not include the code inside-effect-package/set
, onlyside-effect-package/check
. This check runs, and it fails because the flag was never set.It's worth noting that
side-effect-package
has"sideEffects": true
in its package.json, so it should be apparent to any bundler that it contains side-effects.Another point to note is that the issue only occurs if both
preview.js
andButton.jsx
share a side-effect import. If you comment outimport "side-effect-package/check"
and instead uncommentimport "side-effect-package/other"
, all side-effects are bundle correctly and no errors are thrown.I've tried debugging why this particular bundling quirk is occurring, but I can't quite find the right Rollup plugin hook to give me the information I need. Specifically: why are the side-effects from
preview.js
not being include in their entirety in the bundle.This seems like a trivial side-effect issue, but it speaks to a larger discrepancy between vite's dev server and production bundle.
The text was updated successfully, but these errors were encountered: