I have a react application, it has a list of components (kind of key/value – the key is the name of the component and the value is the function e.g () => return (<>hello</>)
and I will like to make use of some components that are not yet in the react application, they are on server, which means I will have to send the code from the server then the frontend needs the function (component) to be registered among the existing ones. I am using a python server, I have folder of the components, when the frontend requests for a file (component), the server reads the content of the requested file then sends it to frontend (which means it’s a string).
On the frontend, I have this code:
useEffect(() => {
getComponent('Test').then(async (res: any) => {
const blob = new Blob([res], { type: 'text/javascript' });
const moduleUrl = URL.createObjectURL(blob);
// Dynamically import the module from the blob URL
const dynamicModule = await import(/* @vite-ignore */ moduleUrl);
setComponent(() => dynamicModule.default);
addComponent('Test', dynamicModule.default || dynamicModule);
});
}, []);
This code now request for a file (component) ‘Test’ from the server and it returns the code, then I tried reading the code and get the default which is supposed to be a function, then register the function as a component.
The test file can be a JSX file, a compiled file etc
The Test file contents I’ve tried and their errors are:
Code in Test.js
const Hello = () => {
return (
<>Hello man</>
)
}
export default Hello
Error:
Uncaught (in promise) SyntaxError: Unexpected token '<'
Code in Test.js
import { jsx as _jsx } from "react/jsx-runtime";
const Component = () => _jsx("div", { children: "Hello from dynamically loaded component" });
export default Component;
No error, this works but with me specifying the “react/jsx-runtime” in script importmap in my main html, which means if I build my app as a library, it might not work because html is not looked into when building. So I don’t want to touch the index.html.
I’ve tried using parcel and babel to build the component, then sends to frontend with the same code on frontend, sometimes the errors are: react is not defined
, Cannot set Component to r undefined
Note: The component to be registered can make use of any react library also to build the component.
I tried making use of a CDN URL directly to import:
const dynamicModule = await import(
/* @vite-ignore */ "https://res.cloudinary.com/devyusuf/raw/upload/v1719594913/folder/App.js"
);
setComponent(() => dynamicModule.default);
But got this error: Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec.
Tried this also:
const resp = await fetch(
'https://res.cloudinary.com/devyusuf/raw/upload/v1719594913/folder/App.js'
);
const res = await resp.blob();
const blob = new Blob([res], { type: 'text/javascript' });
const moduleUrl = URL.createObjectURL(blob);
const dynamicModule = await import(/* @vite-ignore */ moduleUrl);
setComponent(() => dynamicModule.default);
Got this error: Uncaught (in promise) SyntaxError: Unexpected token '<' (at
the unexpected token at is where the jsx tag is in App.js (<>
)
What’s the best way or working way to make this work.