Cannot run editor with Vite - @loadable/components has hard dependency on Webpack
tedtramonte opened this issue ยท comments
Describe the bug
One of the editor's dependencies is essentially hardcoded to only work with Webpack. From googling all day, it seems to only affect people attempting to SSR, but I'm being plagued by Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
while developing using Laravel and Vite.
I get a flash of the editor and then it crashes providing me four errors, they're all essentially the same. Here's the first:
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of `InnerLoadable2`.
InnerLoadable2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-XHZZXWFJ.js?v=a5a3123b:14341:34
LoadableWithChunkExtractor2
Loadable
div
node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js/withEmotionCache2/<@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AWQIRVGD.js?v=a5a3123b:2352:50
Avatar2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-IULQHNQI.js?v=a5a3123b:3056:31
li
node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js/withEmotionCache2/<@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AWQIRVGD.js?v=a5a3123b:2352:50
ListItem2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AMXIV5BI.js?v=a5a3123b:5291:30
div
Draggable@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-XHZZXWFJ.js?v=a5a3123b:15473:17
Item@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-XHZZXWFJ.js?v=a5a3123b:15502:16
ul
node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js/withEmotionCache2/<@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AWQIRVGD.js?v=a5a3123b:2352:50
List2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AMXIV5BI.js?v=a5a3123b:3094:30
div
node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js/withEmotionCache2/<@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AWQIRVGD.js?v=a5a3123b:2352:50
Paper2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-JRYMQJFO.js?v=a5a3123b:126:30
node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js/withEmotionCache2/<@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AWQIRVGD.js?v=a5a3123b:2352:50
Transition2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-BWKZJDK5.js?v=a5a3123b:84:30
Slide2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-IULQHNQI.js?v=a5a3123b:5630:17
div
node_modules/@emotion/react/dist/emotion-element-cbed451f.browser.esm.js/withEmotionCache2/<@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AWQIRVGD.js?v=a5a3123b:2352:50
Drawer2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-IULQHNQI.js?v=a5a3123b:5925:31
Portal4@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-XHZZXWFJ.js?v=a5a3123b:15001:20
PluginDrawer<@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-XHZZXWFJ.js?v=a5a3123b:15562:16
EditorUI_default<@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6491:12
div
StickyWrapper@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6532:18
div
BlurGate@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6090:18
InnerThemeProvider@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AWQIRVGD.js?v=a5a3123b:5834:17
ThemeProvider2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AWQIRVGD.js?v=a5a3123b:5576:7
ThemeProvider3@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-AWQIRVGD.js?v=a5a3123b:5844:7
Provider@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-XHZZXWFJ.js?v=a5a3123b:8555:15
ReduxProvider@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-XHZZXWFJ.js?v=a5a3123b:9299:15
EditorStoreProvider@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6216:18
DndProvider2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-XHZZXWFJ.js?v=a5a3123b:11272:22
DndProvider2@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6029:18
CallbacksProvider@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6113:18
RenderOptionsProvider@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6349:18
OptionsProvider@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6311:18
Provider@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6374:12
EditableEditor@http://127.0.0.1:5173/node_modules/.vite/deps/EditableEditor-KHOPL575.js?v=a5a3123b:6602:15
InnerLoadable2@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-XHZZXWFJ.js?v=a5a3123b:14341:34
LoadableWithChunkExtractor2
Loadable
Editor@http://127.0.0.1:5173/node_modules/.vite/deps/chunk-3SQDUMP4.js?v=a5a3123b:390:12
CmsEditor@http://127.0.0.1:5173/resources/js/cms/editor/CmsEditor.tsx:24:37
That's a lot of chunking garbage, so I dove in and here's the function being referred to:
function InnerLoadable2(props) {
var _this;
_this = _React$Component.call(this, props) || this; // <---
_this.state = {
result: null,
error: null,
loading: true,
cacheKey: _getCacheKey(props)
};
invariant2(!props.__chunkExtractor || ctor.requireSync, "SSR requires `@loadable/babel-plugin`, please install it");
if (props.__chunkExtractor) {
if (options.ssr === false) {
return _assertThisInitialized(_this);
}
ctor.requireAsync(props)["catch"](function() {
return null;
});
_this.loadSync();
props.__chunkExtractor.addChunk(ctor.chunkName(props));
return _assertThisInitialized(_this);
}
if (options.ssr !== false && (ctor.isReady && ctor.isReady(props) || ctor.chunkName && LOADABLE_SHARED.initialChunks[ctor.chunkName(props)])) {
_this.loadSync();
}
return _this;
}
So not very helpful. Scrolling up, the sourcemap is node_modules/@loadable/component/dist/loadable.esm.js
.
To Reproduce
// CmsEditor.tsx
import React, { useState } from 'react';
import type { Value } from '@react-page/editor';
import Editor from '@react-page/editor';
import slate from '@react-page/plugins-slate';
const cellPlugins = [slate()];
export default function CmsEditor() {
const [value, setValue] = useState<Value | null>(null);
return (
<Editor cellPlugins={cellPlugins} value={value} onChange={setValue} />
);
}
// edit.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import CmsEditor from './CmsEditor';
ReactDOM.render(<CmsEditor />, document.getElementById('editor'));
// vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
react(),
laravel({
input: [
'resources/js/edit.tsx',
],
refresh: true,
}),
]
});
Expected behavior
The editor should load without crashing.
Desktop (please complete the following information):
- OS: Fedora 35
- Browser: Firefox
- Version: 103.0.1 (64-bit)
Additional context
So just for fun:
- I've tried running in React 18 and 17
- I've tried running in React's classic runtime mode
- I've tried passing the
@loadable/babel-plugin
to the React Vite plugin - Probably some other stuff
All of the above doesn't change the runtime behavior. At some point today I believe I saw a log or followed some code that indicated it was crashing while trying to load the bottom toolbar.
Additionally while putting this all together, I noticed @emotion
is mentioned in the errors too. I hope that that isn't the root cause here. I see react-admin
uses it as well, but I just upgraded our years old pre 1.0 admin dashboard to use React 18 and this same Vite build process with no issues.
I did some research on @loadable/components
and lazy loading in general:
- They will not be supporting Vite any time soon, if ever: gregberge/loadable-components#833
- The project seems relatively dead: gregberge/loadable-components#718
- React as an organization no longer endorses it: https://github.com/reactjs/reactjs.org/pull/4499/files#diff-fe53b6d2b7c07165bfce8953484a8f840fe8424ab0989f0dbdc0fe851c840bf7L86
- Currently nobody is really sure if there's a good way to lazy load components in React
Anyway, Vite is really taking off and I held off trying it until it started shipping with new Laravel projects and I have to say it's leagues better than Webpack, so I feel it's safe to call this a bug (I'm pretty unwilling to go back, though, so maybe I'm biased).
thx, I will have a look at this.
its important that:
- it still runs on react 17
- it properly does code spitting in nextjs and other platforms
- it does not increase bundle size significantly
Those are all good points that I talk about in the linked PR. The main takeaway is that SSR with the native React lazy loader is unavailable in React 17. I understand if that's a dealbreaker for you, and in that case you can just ignore the PR entirely lol
Those are all good points that I talk about in the linked PR. The main takeaway is that SSR with the native React lazy loader is unavailable in React 17. I understand if that's a dealbreaker for you, and in that case you can just ignore the PR entirely lol
not a dealbreaker of course, at some point we will might need to make react 18 the default requirement, but i think its still too early.
Having said that, SSR is not an issue here, all lazy loaded components in ReactPage should not be rendererd on the server, as it makes nearly no sense. The <Editor />
component itself should just render the static version on the server (same as with readOnly=true
. I think this is doable with react 17 and suspense+lazy, but i never tried it.
(I actually never used lazy+suspense, because in most cases I would want the component to be rendered on the server, which was (I think) not possible with react 17. ReactPage is a rare exception where server rendering is not desired)
Edit: I might merge it to a alpha or beta channel so we can release and test it directly from npm
๐ This issue has been resolved in version 5.0.3 ๐
The release is available on:
v5.0.3
- GitHub release
Your semantic-release bot ๐ฆ๐