I'm trying to set up react-rails for my app (https://github.com/reactjs/react-rails).
I had no problem getting it to set up initially, but I'm anticipating a lot of different individual components so I want to organize my /javascript/components folder neatly.
So I have something like this
components
character
avatar-selector
AvatarSelector.tsx
HomeLogo.tsx
The AvatarSelector.tsx exports the component as default.
And I have
const componentRequireContext = require.context("components", true);
const ReactRailsUJS = require("react_ujs");
ReactRailsUJS.useContext(componentRequireContext);
in both packs/application.js and packs/server-rendering.js
When I render the HomeLogo component everything works fine both with and without prerender.
When I then go to render the component with react_component('character/avatar-selector/AvatarSelector', avatar_props, prerender: false) it also works fine.
But when I switch to prerender: true it gives an error.
ExecJS::ProgramError: Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.>" when prerendering character/avatar-selector/AvatarSelector
I have already tried directly adding
const AvatarSelector = require('../components/character/avatar-selector/AvatarSelector')
to my packs and trying to render the component as AvatarSelector but I still get the same error.
I think one of the core issues is that module lookup uses try...catch. While the errors are logged to the console shim, that typically doesn't help as a later error (such as the invariant violation) will lead to a fatal error (triggering a 500). If that could be refactored to be a bit more intentional based on environment (instead of just reacting based on exceptions, or at the very least, throwing if the caught exception isn't very specific)
Reference - https://github.com/reactjs/react-rails/issues/264