-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ssrLoadModule fails to respect preact/compat aliases, while the SSR bundle does respect preact/compat aliases #15503
Comments
Start a new pull request in StackBlitz Codeflow. |
It looks like currently Vite tries to externalize https://stackblitz.com/edit/vitejs-vite-mudrh8?file=repro.mjs I'm not sure but maybe Vite can safely do this automatically. For example, vite/packages/vite/src/node/plugins/importAnalysis.ts Lines 496 to 498 in 5684fcd
|
Good point. I haven't thought about that, but I think that's what's explained by that warning https://vitejs.dev/guide/ssr.html#ssr-externals, meaning that for example Speaking of dev/prod difference, I think your output js file Further trick to mitigate this would be to put such sub dependencies into |
I got past the error by setting:
in However, the
which means that something is fundamentally broken in preact, i.e. that I posted on the
It's surprising that the bundle path and development path can differ so dramatically. I'll note that |
It's a little difficult to diagnose without concrete reproduction, so I would appreciate if you can provide one. On a related note, one thing come to my mind is that, having For example, |
It seems like
This doesn't help though. I'll work on a reproduction. |
https://github.com/jsamilow/preact-vite-error-repro Here's my effort at a minimalistic reproduction. Unfortunately, this repro breaks for both dev and prod, whereas in the real code it only breaks in dev. Nevertheless, the issue is the same— Steps:
You can do
for the production path. You should see:
|
Hey, thanks for getting back with the reproduction. However, your repro still looked complicated, so I stripped out quite a lot and ended up with this https://github.com/hi-ogawa/repro-vite-preact-15503, which hopefully shows the same error you're experiencing. My observation so far is that it's probably esm/cjs dual package issue of preact https://nodejs.org/api/packages.html#dual-commonjses-module-packages where your own code is using esm-version of preact but To make this work on dev, I think you would need to manage To make this work on build, I think it's easier because you have more control on build output (compared to dev where vite forces user code to use And finally it's probably a little crazy idea. I was wondering why react doesn't experience this kind of issue on Vite SSR, then I realized react is cjs only package. In hi-ogawa/repro-vite-preact-15503#2, I explore this idea and patched preact packages to remove esm exports from their package.json and it actually seems to work... I just tried to give as much information as I can, but employing any of these tricks in the actual project might be difficult. Overall, I feel this is preact ecosystem issue/limitation in terms of react compatibility (while Vite SSR still provides some sort of workaround), so I might not be able to help this case further. But I hope you got some idea about the underlying issue. |
Thank you for your reply and persistence in investigating this! You are exactly right about the problem, and patching I believe there are interesting subtleties here, and I hope elaborating on them will provide future help to anyone dealing with an inscrutable dual package error. While But I was wrong. Vite chose to load the CJS version of
You can see that the ESM version of preact is imported, while the CJS version of It looks looks like vite ignores
(I can push a branch to your repro if you grant me permission but this modification is so small I don't think I need to push it.) You will find that the code is no longer broken. It's surprising to me that Vite's resolution in resolveExportsOrImports logic will use I would have expected Vite to always prefer a package's ESM version as long as it is available. I am not sure this can be described as a bug, because there might be a good reason for Vite to resolve modules using this logic. But the behavior is surprising at very least. Although Vite removed the Thanks once again for looking deeply at this. |
Keep in mind that, since Even if you fixed that by preprocessing these modules, many do access browser globals in these entry points. Trying to consume this entry might be more headaches than it's worth. That library should be using |
Describe the bug
I'm migrating an existing repo from Webpack to Vite.
We use preact, and rely on aliasing
react
andreact-dom
topreact/compat
in the SSR bundle. Vite handles the aliases as expected when it bundles the SSR code for production. But when loading SSR for development usingvite.ssrLoadModule
, Vite fails to respect thereact->preact/compat
alias, even though it respects other aliases invite.config.js
. I have provided a minimalist reproduction of the issue below.If this is not a bug and is in fact the expected functionality, the discrepancy between prod and dev is unexpected to say the least. I was debating whether this is a Vite or Preact issue, but the fact that the behavior differs within Vite leads me to think it is a Vite issue.
For some background information, which is not necessary to understand the problem, I found that SSR worked when I loaded it from a bundle:
but failed when I loaded it using
ssrLoadModule('/frontend/ssr.js')
withThe issue is that React's renderer is incompatible with
preact-render-to-string
. In the bundle case, Preact's renderer is used as desired, but in thessrLoadModule
case, React's renderer is used.Reproduction
https://stackblitz.com/edit/vitejs-vite-nxei8z
Steps to reproduce
npm install --legacy-peer-deps
To run it in production mode, first do
npm run build:vite-ssr
to create the SSR bundle. ThenNODE_ENV=prod node -r esbuild-runner/register launch.js
. You should see it printreact version 17.0.2
. This is what's expected, aspreact/compat
provides a hardcoded version of 17.0.2.To run it in development mode, do
NODE_ENV=development node -r esbuild-runner/register launch.js
. You should see it printreact version 16.14.0
. This is not expected, and indicates that Vite failed to mapreact
topreact/compat.
The discrepancy in versions between the bundle and
ssrLoadModule
indicates that different libraries are being loaded.But strangely,
ssrLoadModule
does respect thetestAlias
that I added invite.config.js
. If you comment out that alias, everything breaks.I'm skeptical this can be a bug given how dead simple it is to reproduce, but I cannot find anything in the documentation or Preact SSR examples that predicts this discrepancy between bundle and development.
System Info
The text was updated successfully, but these errors were encountered: