vitejs / vite-plugin-react-swc

Speed up your Vite dev server with SWC
MIT License
778 stars 50 forks source link

window is not defined in WebWorkers #163

Closed val-o closed 8 months ago

val-o commented 8 months ago

Describe the bug If you are using Vite with barrel exports, you might end up with situation when you have a barrel file like this:

file: dashboard/index.ts tsexport from './helpers' export from './components'

If there is a web worker (or any other worker) which imports helper from dashboard tsimport {dashboardHelpers} from './dashboard' // some non-ui related work

Vite will load components anyway (that's how it works now) and there will be ReactRefresh injected code in all of the components codes, which will fail with following error, since there are hard references to window

Uncaught ReferenceError: window is not defined

Exptected: Plugin should have some checks inside injected code which guards from failing inside non-window contexts

ArnaudBarre commented 8 months ago

Yeah I will fix that, but you will be better moving off barrels files anyway, this slow down most tools: https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-7/

ArnaudBarre commented 8 months ago

So I wanted to add the same support than in the Babel plugin, but I discovered that this is barely working because as soon as you use a hook, the ReactRefresh transformation inject a global call to $RefreshSig$ which fails. Given that adding this will just make errors more obscured and that in other cases this is just hiding the fact that you have too much code bundled into your worker because of barrels. Rewrite your exports and imports will make your app load faster.

For anyone that find this, better support in worker requires either:

deathemperor commented 6 months ago

@ArnaudBarre is there a workaround to this window is not defined in WebWorkers? I'm open for patches.

ArnaudBarre commented 6 months ago

What causes some HMR code to end-up in your bundle? Most of the time the solution is just to review imports/file split which improve the size of the bundled worker

deathemperor commented 6 months ago

What causes some HMR code to end-up in your bundle? Most of the time the solution is just to review imports/file split which improve the size of the bundled worker

I don't get what you mean. Are you talking about separate worker files so that they won't get detected by the plugin => this error won't appear? I actually get them first time running which I think is not a hot reload?

ArnaudBarre commented 6 months ago

Most of time the issue happens when you import JSX inside a worker. Is it you case? What file containing HMR code is imported by your worker?

deathemperor commented 6 months ago

I'm experimenting with this https://github.com/Shopify/remote-ui/tree/main/examples/kitchen-sink-vite/app/react-worker. It enables rendering JSX inside worker.

ArnaudBarre commented 6 months ago

In that case I would recommend to not use any React plugins and let esbuild do the JSX transpilation. This will lead to full reload on every edit but for web workers there is no choice. Having HMR for web code and no-op for webworker until implemented is something discussed here: https://github.com/vitejs/vite/pull/15262#issuecomment-1859245374

If using React component inside webworker becames a thing, I hope someone will add HMR support to webworkers instead of having no-op code and bad HMR experience

deathemperor commented 6 months ago

thanks for the advice, good one.