storybook: [Bug]: 7.0.0-beta.28 HMR not working with @storybook/react-vite
Describe the bug
HMR doesn’t seem to be working with storybook react with the vite builder.
Package version: @storybook/react-vite@7.0.0-beta.28
Wondering if anyone has anymore context on why the following options are set for the vite builder dev server config: Reference: https://github.com/storybookjs/storybook/blob/v7.0.0-beta.28/code/lib/builder-vite/src/vite-server.ts#LL18-L21
hmr: {
port: options.port,
server: devServer,
},
It seems to work fine if the vite hmr options are removed which allows vite to initialize its own websocket server for hmr.
With the existing config, the websocket server doesn’t seem to be able to receive the upgrade event below. Reference: https://github.com/vitejs/vite/blob/v4.0.4/packages/vite/src/node/server/ws.ts#L99-L105
wsServer.on('upgrade', (req, socket, head) => {
if (req.headers['sec-websocket-protocol'] === HMR_HEADER) {
wss.handleUpgrade(req, socket as Socket, head, (ws) => {
wss.emit('connection', ws, req)
})
}
})
To Reproduce
No response
System
Environment Info:
System:
OS: macOS 13.1
CPU: (8) x64 Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
Binaries:
Node: 19.4.0 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 9.2.0 - /usr/local/bin/npm
Browsers:
Chrome: 108.0.5359.124
Edge: 109.0.1518.52
Firefox: 85.0.2
Safari: 16.2
Additional context
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 2
- Comments: 17 (10 by maintainers)
It seems like with the new version (v7.0.0-beta.30) I get this when opening the storybook preview:
w00t!! I just released https://github.com/storybookjs/storybook/releases/tag/v7.0.0-beta.30 containing PR #20654 that references this issue. Upgrade today to the
@next
NPM tag to try it out!Closing this issue. Please re-open if you think there’s still more to do.
I finally figured out the issue after an unreasonable amount of debugging on bundled vite server code 😂. The
vite-plugin-externals
plugin isn’t properly following the vite api for modifying config. Fix here: https://github.com/crcong/vite-plugin-externals/pull/27. After the fix is published, https://github.com/storybookjs/storybook/pull/20655 could probably be merged in to revert the addition ofdisableInServe: true
.Could make sense to move to any internal plugin too if the plugin is as simple as https://github.com/storybookjs/storybook/pull/20698, but otherwise this should fix the issue.
If anyone is curious, it’s because plugin configs are deeply merged by vite in the config hook.
https://github.com/vitejs/vite/blob/v4.0.4/packages/vite/src/node/config.ts#L1109
Since
vite-plugin-externals
was passing in the entire config to be merged, the merge code was recursively merging the hmr server from@storybook/builder-vite
with itself.https://github.com/storybookjs/storybook/blob/v7.0.0-beta.29/code/lib/builder-vite/src/vite-server.ts#L20
I sent them an email as well this morning. But yes, I think if we don’t get a response in a couple of days we’ll need to take a different approach.
See #20655
¡Ay Caramba!! I just released https://github.com/storybookjs/storybook/releases/tag/v7.0.0-beta.36 containing PR #20698 that references this issue. Upgrade today to the
@next
NPM tag to try it out!Closing this issue. Please re-open if you think there’s still more to do.
Thank you so much for your time debugging this! 🎉I will ask internally, whether we want to wait for a fix of vite-plugins-externals, or moving that plugin internally.
FYI: @ndelangen, @IanVS
It looks like it’s related to this issue it was mentioned in https://github.com/storybookjs/builder-vite/issues/55#issuecomment-1396899350. I was using pnpm and the hoisting workaround mentioned does work for me. Seems fine with the production build.
Also trying to look into why vite-plugin-externals is breaking HMR from the websocket upgrade route.
Yes, but with pnpm (and maybe yarn pnp), it needs to also be imported in the right context. Because this is being loaded in the browser, we need to make sure it’s in the user’s package.json. I remember now, previously we imported these internal packages from the framework, which re-exported from preview-api, etc. Now we rely on the pre-bundling, which is turned off in dev now, so it’s breaking. I am guessing that it still works fine in builds.
It’s literally a dependency of the vite-builder?! https://github.com/storybookjs/storybook/blob/8285f7b0badca6c798f51e8bd16463e6fd397c07/code/lib/builder-vite/package.json#L54
Also noticing that HMR broke after upgrading. I’ve been testing different versions, and seems like it broke with beta.26 - Maybe it’s caused by #20594 ?
Changing a component causes it to skip printing the
invalidate
message: In beta.25:In beta.26: