-
-
Notifications
You must be signed in to change notification settings - Fork 125
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
Cannot import commonjs module from server component #110
Comments
Hmm, I thought it works, but it doesn't. (btw, |
Fair point, this was the easiest way to trigger the error for me but I also was able to trigger the error by importing a CJS-only package from node_modules I think these days it's pretty unlikely for packages to be not have any ESM support at all, but this is pretty critical for the electron use case (electron is CJS only). |
@PerfectPan @nksaraf |
No I think within your project you shouldn't really have cjs.. that way vite is ESM only.. it just knows what to do about cjs files in node_modules. But also I could be wrong to pinging @patak-dev |
Note, although the example uses CJS inside my project, this error also appears for CJS inside node_modules. IMO both of these behaviours are strange, in a Node.js ESM environment you are able to import a CJS module without issue. I wondered if there was a way to mark the CJS module as external so that it would be simply |
Yeah. |
To be honst, I am a newbie to vite. I just start learning vite from waku lol. I tried to read the source about ssrLoadModule part and I found the basic rule is that if your code is not external based on https://vitejs.dev/config/ssr-options.html#ssr-external , it cannot use commonjs, otherwise it will based on the node runtime behavior. When ssrLoadModule being called, vite will transform your code first and wrap your code into a AsyncFunction. Transform stepBasically it will resolve all the import an export statement and rewrite to a load function, you can see the code here https://github.com/vitejs/vite/blob/main/packages/vite/src/node/ssr/ssrTransform.ts#L126. example:(more can see the test code https://github.com/vitejs/vite/blob/main/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts#L10) import foo from 'vue';console.log(foo.bar)
// after
const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\");
console.log(__vite_ssr_import_0__.default.bar) Wrap stepAs you can see, for import statement it will be replaced by __vite_ssr_import, this is injected by the vite by wrapping the code into a async function. https://github.com/vitejs/vite/blob/main/packages/vite/src/node/ssr/ssrModuleLoader.ts#L216 So the load result is an async function and will be executed by the user side. It is a little like use the function closure to emulate a import / export environment instead of bundling all the code into a file like webpack. So as you can see, the final code is just a function, and the current situation is esm, node esm does not exist require or module, so it will throw error. A piece of code can prove my point. However, there is a workaround or by design pattern provided by vite which is https://vitejs.dev/config/ssr-options.html#ssr-external. When you external the whole third package, the resolve id will be the original instead of the parsed absolute path. Once vite detect it is external package, vite will use the node loader to handle it. The code is here https://github.com/vitejs/vite/blob/main/packages/vite/src/node/ssr/ssrModuleLoader.ts#L265. When you try to use import() call in esm, it can handle cjs correctly. Another workaround I think maybe you can use @rollup/plugin-commonjs to convert cjs to esm which I have not tried yet. Apparently I hide a whole lot of details like the plugin transformation or the optimize thing, I just read the basic code but I think it is enough to explain this situation. |
And for your anothor issue tom-sherman/waku-desktop#2, simply add external can not resolve all the problem. You still will get a following runtime error:
This is because the whole code executes in a node environment instead of electron. So when you import you will only get the execute path of Electron just like the doc says Maybe you should encapsulate a remote call for server and electron environment to communicate so that you can use the original electron ability. |
In waku-desktop the "server" is the electron main process, so it should be running in that environment. Like you though I'm learning these things as I go, it's possible I've misunderstood something. |
I know what you mean. But waku will create a worker thread to handle the rsc file(https://github.com/dai-shi/waku/blob/main/src/lib/middleware/rsc/worker-api.ts#L12), so user code actually is running in another node environment. |
Hmm, ok - yep that is an issue. I think changing this approach would solve my electron problem then. I understand that RSC + SSR need to run in two separate processes (or at least react-server-dom-webpack assumes this to be the case) but Waku with SSR turned off shouldn't need to spin up any child processes when SSR is disabled I don't think. |
Can anyone try with Waku v0.17.0? I don't expect it's solved, but would the error message be different? |
TIP: This is one way to use cjs module: |
Another solution is to externalize the library. I think it's a valid workaround. waku/packages/website/vite.config.ts Lines 4 to 10 in 7398b45
Please note that this is DEV-only issue now. @tom-sherman commonjs should work for PRD bundling. |
So, this looks like vite loadSsrModule cannot handle cjs bundle. Related issue: vitejs/vite#3024 |
As we have a workaround, I don't consider this a bug, but it would be nice to provide better DX. |
When trying to import a CJS module from a server component I get an error in dev & production
Minimal reproduction: tom-sherman/waku-example@77cf350
The text was updated successfully, but these errors were encountered: