vanilla-extract-css / vanilla-extract

Zero-runtime Stylesheets-in-TypeScript
https://vanilla-extract.style
MIT License
9.5k stars 287 forks source link

HMR not working in Webpack 5 (Storybook) with Vanilla Extract #905

Open hanshank opened 1 year ago

hanshank commented 1 year ago

Describe the bug

Hey Vanilla Extract team. I'm a dev for a rather large Tech company and we are exploring using Vanilla Extract in some of our apps. I've encountered a bug when trying to setup for Storybook/webpack, as per the steps in your wiki here: https://vanilla-extract.style/documentation/integrations/webpack/

Please see repro steps and explanation below:

Run repro repo locally and then:

  1. While Storybook is running in the browser (Chrome), navigate to src/stories/button.css.ts
  2. Make a change to the styles, e.g. change fontSize property to '100px'.

What happens HMR kicks in but Storybook can no longer find the component, due to error as shown in screenshot below. I have to do a full page reload to get the updated component

What should happen HMR kicks in and the component styles gets updated without any issues.

I don't know what's going on, but I did follow the install guide in your wiki here: https://vanilla-extract.style/documentation/integrations/webpack/

After HMR in Storybook kicks in I'm getting the following:

Screen Shot 2022-11-04 at 5 17 25 PM

You might say, why is this not a Storybook issue? Well... It's using Webpack 5 and I don't see why there should be any issues since I followed the wiki steps for setting up Vanilla Extract with Webpack 🤷‍♂️

Reproduction

https://github.com/hanshank/storybook-and-vanilla-extract

System Info

System:
    OS: macOS 12.6
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 80.75 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.13.1 - ~/.nvm/versions/node/v16.13.1/bin/node
    npm: 8.1.2 - ~/.nvm/versions/node/v16.13.1/bin/npm
  Browsers:
    Chrome: 107.0.5304.87
    Firefox: 106.0.1
    Safari: 16.0
    Safari Technology Preview: 16.4
  npmPackages:
    @vanilla-extract/css: ^1.9.1 => 1.9.1 
    @vanilla-extract/webpack-plugin: ^2.2.0 => 2.2.0 
    webpack: ^5.74.0 => 5.74.0

Used Package Manager

pnpm

Logs

No response

Validations

ybot1122 commented 1 year ago

Hello; Since Storybook is using splitChunks optimization: https://github.com/storybookjs/storybook/blob/next/code/lib/builder-webpack5/src/preview/iframe-webpack.config.ts#L282-L284

This is not the default value for webpack (https://webpack.js.org/plugins/split-chunks-plugin/)

All you have to do in your .storybook/main.js is to delete config.optimization.splitChunks and should be fixed. Hope this works for you.

hanshank commented 1 year ago

@ybot1122 That's a great find! It does fix the HMR issue for me!!!

I would rather not delete the splitChunks optimization, but I found another approach in this issue: https://github.com/vanilla-extract-css/vanilla-extract/issues/746#issuecomment-1207390899 - I modified @danielberndt's approach ever so slightly to maintain all the default properties of the splitChunks object. But it basically his solution I am using, so thank you!

TLDR:

  1. Copy the official default splitChunks object from Webpack: https://webpack.js.org/plugins/split-chunks-plugin/#optimizationsplitchunks. Wish there was a way to extend the default Webpack config instead, but according to this comment that's not an option 😢
  2. In .storybook/main/.js add this to webpackFinal:
module.exports = {
  // ... other config properties
  webpackFinal: async (config) => {
     // vanilla extract setup

    // add this
    if(process.env.NODE_ENV === 'development') {
      config.optimization = {
        ...config.optimization,
          splitChunks: {
             chunks: 'async',
             minSize: 20000,
             minRemainingSize: 0,
             minChunks: 1,
             maxAsyncRequests: 30,
             maxInitialRequests: 30,
             enforceSizeThreshold: 50000,
             cacheGroups: {
               defaultVendors: {
                 test: `[\\/]node_modules[\\/](?!.*vanilla-extract)`, // this is the line that fixes it
                 priority: -10,
                 reuseExistingChunk: true,
               },
              default: {
                minChunks: 2,
                priority: -20,
                reuseExistingChunk: true,
              },
          },   
        }
      }
    }
  }
}

The cacheGroups.defaultVendors.test property was changed from the default /[\\/]node_modules[\\/]/ => [\\/]node_modules[\\/](?!.*vanilla-extract)

If someone has a better solution I'm all ears! This is definitely a workaround and I think it would be awesome if at some point the underlying Vanilla Extract source code could take care of this scenario where splitChunks is used in a project's Webpack config