Closed songquanpeng closed 1 year ago
Not encountered this error. Can you have a try after upgrade vite?
PS D:\Project\Go\snippet-manager\web> vite --version
vite/2.0.1 win32-x64 node-v14.15.3
Dev: Production:
And you can check out the deployed version here, built with Github Action: https://snippet.justsong.cn/
I ran into the same issue using latest Vite version.
The title of the issue is very vague as this error is displayed by minified React instead of ANY React error. So it can be anything really.
But in both our cases, this is the actual error Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
The first thing to do in this case is to debug the app in order to have more details: Use minify and dev mode in your vite.config.js
in order to get the real issue with the possibility to inspect in the browser dev tools.
export default defineConfig({
plugins: [reactRefresh()],
mode: "development",
build: {
minify: false,
}
});
In my case it was coming from using react-switch
. And I hacked it to work using the following (don't tell anyone about this)
import S from "react-switch";
const Switch = S.default? S.default: S
console.log(S); // inspecting
Basically this is the content of the import {__esModule: true, default: ƒ}
The react-switch library is built as cjs
so this is probably a cjs
compatibility issue for Vite's Rollup build configuration ?
If you follow the debugging steps, you will discover that the culprit in your case is react-highlight
In order to reproduce the issue, you need to:
npx vite build
npx http-server dist --port 3002
It's because esbuild is checking for __esModule at runtime and rollup is not. So it will happen to any library that has an entry point with
module.exports = require("./something");
Since this file does not include the 'magic string' __esModule
as checked by https://github.com/rollup/plugins/blob/master/packages/commonjs/src/generate-exports.js#L82 it's not converted correctly.
vite dev |
vite build |
|
---|---|---|
import Switch from 'react-switch'; Switch |
ok | |
import Switch from 'react-switch'; Switch.default |
ok | |
import Switch from 'react-switch/dist/react-switch.dev.js'; Switch |
ok | ok |
So need to raise a bug in rollup for this.
Unsurprisingly, it's a known issue mentioned in https://github.com/rollup/plugins/issues/481 but it doesn't seem like there will be a solution very soon.
One thing to note is that the node behaviour is mutually exclusive with supporting __esModule. When running natively from Node, Switch.default
would be the only correct option. In the end the best way would probably to ask the library author to publish an esm version to avoid this problem completely.
It's because esbuild is checking for __esModule at runtime and rollup is not
Then we should issue a big warning at dev time about this behaviour. It's a critical bug (in the libraries) that affects the Vite experience drastically.
Yup, same problem here: https://github.com/vitejs/vite/issues/2692.
After looking into this some more, I think vite should switch to behave the same as rollup. That way it would be consistent with how node works (and snowpack as well).
For now, importing a commonjs module should probably show a warning somewhere.
@ntkoopman would you expand a bit in what needs to be changed in Vite? A PR would be great so we can discuss what the implications are there (from anyone that is following this issue)
Agree about the warning in the meantime in case that change is not easy to land, PR welcome for that patch too
So I already changed my mind again, since changing the dev behaviour will still break dependencies. So, the best case would still be that it gets fixed in rollup. I tested with a commonjs plugin I wrote and it seems to work for us for now:
import cjs from 'rollup-plugin-cjs';
export default defineConfig({
build: {
rollupOptions: {
input: {
index: resolve(__dirname, 'src/index.html'),
},
plugins: [cjs()],
},
commonjsOptions: {
exclude: [/./],
},
},
});
I looked into returning a warning, but decided not to, because if it's possible to detect the issue it should be possible to fix it..
I'll continue on the commonjs plugin and see if I can fix it there (or maybe it's just a configuration option that's missing?) now that I have some unit tests.
Hacky solution in my case
In my case it was coming from using
react-switch
. And I hacked it to work using the following (don't tell anyone about this)import S from "react-switch"; const Switch = S.default? S.default: S console.log(S); // inspecting
Basically this is the content of the import
{__esModule: true, default: ƒ}
The react-switch library is built as
cjs
so this is probably acjs
compatibility issue for Vite's Rollup build configuration ?
I used this to fix this issue cropping up with react-no-ssr.
This issue is complete blocker for me from using Vite in my React production apps.
In my case, the issue does not show up in the development mode (it works completely fine there) and it does only show up in production.
The thing is... since a lot of external React components (like react-switch
, react-notfification
, react-select
) uses export default
(unfortunetly) - it forces developer to guess which one of it crashes the app. However, trying setting "development" mode for production build and disabling minifier option doesn't help either, because DevTools also doesn't show me any exact place in the stacktrace where the problem can exist.
Hope this issue will be resolved soon, because I loved using Vite so far 😔
Is there an ETA on at least catching this some way in development?
I'm blocked by the same problem. How are people deploying their apps into production? Is there a workaround in the meantime?
To track down which package was causing the problem, I had to do some grindy work of setting breakpoints in Chrome dev tools (on the error-throwing lines, and in some cases going up the call stack) and then iterating through until I found the culprit. Not an easily reproducible solution, especially since in most cases you're dealing with minified code.
🔥 I'm blocked by the same issue. My team is thinking about stopping using vite, and going back to webpack. Please give more power and fix it as soon as possible.
React + vite doesn't work well in a production environment, need to wait.. :(
Note: This isn't a React-specific or Vite-specific issue, but a Rollup issue (specifically with their CommonJS plugin).
Example: https://github.com/alloc/vite-react-jsx/commit/2db2870f5ad888ed7d4a57e5ba10a82f8bdf80b2
Instead of importing the CJS package directly, use a middle man that unwraps the module.default
property like so:
import S from 'react-switch'
export const Switch = interopDefault(S)
function interopDefault<T>(value: T): T {
return (value as any).default
}
It's ugly, but it works. If 10 people sponsor me on Github for $1 a month, I'll make a plugin that handles this compatibility layer automatically (and maybe even work it into Vite core).
With some heavy trial-and-error I have identified the imports which were causing this and fixed them. A day (not so) well spent... Really a horrible experience for someone using Vite for the first time. The worst thing that can happen is when you get this by importing a componet from one of those "unsafe" libs, then the exception originates from react-dom
and good luck finding why/where. Other imports (like hooks, etc.) will fortunately show up the exact line (with sourcemaps turned on). Plugin for some compat layer would be awesome. @aleclarson how big one-time donation would it require so you start working on this? 😄
@smajl My goal is to increase my sponsor count. I'm the only React-focused maintainer of Vite, so if any of you use React, please sponsor me, or I can't justify sharing my contributions. I recently made vite-react-jsx too.
@aleclarson uncaught at Error: Minified React error #130; visit https://reactjs.org/docs/error-decoder.html?invariant=130&args[]=object&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings. I had the same problem, I like vite but it is still a lot of problems with react production.
@rollup/plugin-commonjs
works for me with the commonjsOptions exclude pattern ntkoopman used (thank you). I don't understand how that works, since that should match any path longer than 0 characters. @rollup/plugin-commonjs
is also used internally in vite, but not passed to rollup.
import { defineConfig } from 'vite'
import commonjs from '@rollup/plugin-commonjs';
// https://vitejs.dev/config/
export default defineConfig({
build: {
rollupOptions: {
plugins: [commonjs()],
},
commonjsOptions: {
exclude: [/./],
},
}
})
Someone should at least rename and pin this issue imo (if documenting or fixing the issue are not viable short term options). Like many others in here I had a terrible onboarding experience with Vite spending hours debugging and finding the solution for this, because some of my dependencies used commonjs-only libraries (example: https://github.com/plurals/pluralize). aleclarson's solution was not viable, as I can't wrap my dependencies import logic, and it didn't import an object with the default
property. It imported an empty object ({}
).
Same issue here with just this:
import React from 'react';
import ReactDOM from 'react-dom';
import JSONTree from 'react-json-tree';
ReactDOM.render(
<React.StrictMode>
<JSONTree data={{ test: 'Hello World' }} />
</React.StrictMode>,
document.getElementById('root')
);
Neither proposed @rollup/plugin-commonjs
or rollup-plugin-cjs
worked for me as I would run into 'x is not a function()'.
@jrmyio Disable minification to see the real error https://github.com/vitejs/vite/issues/2139#issuecomment-802981228
@jrmyio Disable minification to see the real error #2139 (comment)
Thanks, the error is
Uncaught ReferenceError: Cannot access '__çjs$synthetic__' before initialization
at vendor.0646077f.js:1
(anonymous) @ vendor.0646077f.js:1
when using rollup-plugin-cjs
Using @rollup/plugin-commonjs
will keep the React error because cause my example (https://github.com/vitejs/vite/issues/2139#issuecomment-866857521) uses react-json-tree
.
@jrmyio Disable minification to see the real error #2139 (comment)
I did the configuration to disable minification but seems not work for me. Still showing Minify 130 error.
@jrmyio Disable minification to see the real error #2139 (comment)
I did the configuration to disable minification but seems not work for me. Still showing Minify 130 error.
Likewise. How do we get proper errors with stack traces in production? Preferably like CRA. It's very difficult to debug such errors.
Same issue when using react-json-tree
. Workaround in this issue like
import T from 'react-json-tree';
const JSONTree = T.default? T.default: T
didn't work for me. It seems this package have some ESModule import inside itself, but hacking the index is not sufficient.
// lib/JSONNode.js
// ...
var _default = JSONNode;
exports["default"] = _default;
// lib/index.js
var _JSONNode = _interopRequireDefault(require("./JSONNode"));
My workaround is import this module source directly. But it is really tricky and breaking type check.
import JSONTree from 'react-json-tree/src/index'
Same error, using: I don't know, my project grow up, when I'm ready to deploy and publish: ERROR. 😢
Unfortunately, I can only continue to use "CRA + react app rewired" to build, and everything finally starts to work normally.
It was a pain to identify the offending component (react-datetime
in my case), but I found the workaround from @aleclarson and @barankyle worked for me.
It would be great if vite/rollup could identify the offending component at least. This is a real gotcha for people migrating apps from other frameworks (Snowpack and NX in my case), finding everything works beautifully in dev and then hitting unexpected errors in production.
This is a major issue that prevented migration from CRA to Vite. Unfortunately this problem was not discovered until a production build was attempted once everything was working in dev
mode.
Related Discussion: https://github.com/vitejs/vite/discussions/5803
I agree with @jugglingcats that any insights to identify offending components would be helpful. A 'non-minified' 'development mode' build seems like a critical feature for debugging.
Rolling back to CRA. 😢
encounter same issue, is there a solution? thanks!
Any tips on identifying which module causes this when the stacktrace just points to ReactDOM
? Mocking ReactDOM as mentioned by @aleclarson doesn't seem to do anything (only causes a render is not a function
error) so I guess that ain't the source of my issues.
Edit: For future visitors, adding the following to the Vite config file helped:
{
mode: 'development', // < this is important
build: {
minify: false,
sourcemap: true // < this allows the browser to point you to the correct file
}
}
Alas, I've also given up. I've spent one week trying to migrate a CRAv4 project, but it seems like Vite ain't ready yet. Will upgrade to CRAv5 for now, looking forward to trying again in the future. :)
I'm also experiencing this issue with a package I've authored, and I don't understand how to build this package to avoid this issue.
tsc
typescript compiler https://github.com/betagouv/publicodes/blob/master/packages/react-ui/tsconfig.jsonA sum up:
The root problem is that many packages follow a bad practice that breaks Rollup ESM-CJS interop:
react
, they use a CJS entry with mere conditional require()
s to redirect the request to different source modules based on NODE_ENV
. (e.g. https://unpkg.com/browse/react-switch@6.0.0/index.js). The actual source modules are compiled ESM with an exports.__esModule
flag; (e.g. https://unpkg.com/browse/react-switch@6.0.0/dist/react-switch.dev.js)react
, they use default exports in the source;__esModule
flag from the entry module at runtime and only at runtimerequire()
call resolves at runtime.react
). But when there's a default export, it would become nested after Rollup bundling (import Switch from 'react-switch'
returns { default: ... }
).It's easy to work around at the user side with the above-mentioned hack:
import S from "react-switch"; const Switch = S.default? S.default: S console.log(S); // inspecting
But a more general solution might not be that easy, especially since there could be named exports along with default exports in the same module. Detecting such possible breakages seems not easy too because they are resolved at runtime… I'll see what I can do here to help mitigate the issue.
Ideally, these packages should:
You should just make these fail in development as well.
Why you think it's good idea to have these modules working only in development and then fail in prod build?
Thanks you @sodatea for the detailed write up. I've found that the PR that introduced this feature in esbuild provide some interesting additional context https://github.com/evanw/esbuild/pull/1849#issue-1079368644
I agree that the behavior should be the same in dev and in prod modes, which imply either:
Also related: https://github.com/evanw/bundler-esm-cjs-tests#results
Just wanna chime in I ran into this today and while I'm upset it's blocking, I want to encourage sponsoring maintainers like @aleclarson not only for their work so far but so hopefully someday we can get this fixed :)
Question for maintainers: has anyone already tried implementing Evan's idea #2 of pre-bundling dependencies with esbuild in production as well? Do we know how much work that would involve? (I may be able to help)
For anyone looking at this issue, this should hopefully be solved by https://github.com/rollup/plugins/pull/1165, which depends on another big Rollup CJS PR, so I'm not exactly sure when we'll get it all released and updated in Vite, but a fix is in sight at least 👀
If it takes too long, we could also consider patching the Rollup CJS plugin in Vite (it's a small diff when you exclude tests).
:(
I'm about to finish the migration from CRA to Vite, but I found this same error with react-switch
, thanks to this thread I could fix the issue, thanks
But, now I'm wondering if there is another library with the same problem in my project, there is a way to validate more libraries have the same issue?
Hey!! I've just encountered this, and I've realized that rollup has already issued the fix for this in release v22.0.0 https://github.com/rollup/plugins/commit/3bc287cd6ad067a54e69ec17a1869cb12da2e952
Can we get the rollup plugin in vite bumped to v22?
@Kylar13 we're hitting some issues with the update to rollup plugin commonjs v22, in case someone wants to help check out the issue:
I'm completely lost as to how Vite works internally so I am unable to help, but I will add that the library that was giving me issues is https://www.npmjs.com/package/react-phone-input-2, and the fix for now is the one suggested by @haikyuu:
import RPI from "react-phone-input-2";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const ReactPhoneInput = RPI.default ? RPI.default : RPI;
@Kylar13 we're hitting some issues with the update to rollup plugin commonjs v22, in case someone wants to help check out the issue:
Until we manage to make it work, we could stay on v21 and patch it in Vite with https://github.com/rollup/plugins/pull/1165 (it's just a couple of lines of actual code). I believe this would at least allow us to close this issue.
Patching is not ideal, but I bet it would unlock the next level of growth for Vite as this issue is holding back larger codebases from migrating over from Webpack.
Describe the bug
Encountered “Minified React error” in the production environment, the dev environment is fine.
Reproduction
Repo: https://github.com/songquanpeng/snippet-manager/tree/aa02a582c676bd3dcd5254f18d7087bb8a1a7220
My React application is on the
web
folder.System Info
vite
version: 2.0.0Summarization of the root problem
https://github.com/vitejs/vite/issues/2139#issuecomment-1024852072