Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically import React component from external URL and use parent React environment

I have a Main UI into which I want to load a Sub UI in the form of a React Component, which is then integrated through a React.Suspense JSX Tag. The Main and the Sub UI will both be separately bundled with Webpack. The Sub UI is bundled as a Webpack 5 Module Library.

Now, the dynamic loading of the component from an URL seems to be no problem. I can use

var path = "<< some URL to a JS-File in a CDN >>";
var SubUiComponent = React.lazy(() => import(/* webpackIgnore: true */ path));

But because the component that I want to import is bundled with Webpack, another React instance is being used. I have already tried to use Webpack Externals, but there seems to be no way that it can be used in combination with dynamic imports.

When I'm not defining externals, I get the following error:

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See https://reactjs.org/warnings/invalid-hook-call-warning.html for tips about how to debug and fix this problem.

With externals defined in webpack.config.js, I get the expected error:

Uncaught ReferenceError: React is not defined

So, is there a way of bundling a React component "kind of" as a library and then import it into another React Environment and use it there?

like image 382
Christoph Pader Avatar asked Feb 25 '26 20:02

Christoph Pader


1 Answers

Maybe you can try https://github.com/Paciolan/remote-component

const url = "https://remote.../HelloWorld.js";

const HelloWorld = ({ name }) => <RemoteComponent url={url} name={name} />;

const Container = (
  <>
    <HelloWorld name="Remote" />
  </>
);

or https://github.com/Paciolan/remote-module-loader

import loadRemoteModule from "./lib/loadRemoteModule";

const myModule = loadRemoteModule("https://remote.../my-module.js");

myModule.then(m => {
  const MyComponent = m.default();
  console.log({ MyComponent });
});
like image 169
Jaider Avatar answered Feb 27 '26 10:02

Jaider