Skip to content

Commit

Permalink
testing with @module-federation/runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
ayonix committed Jan 12, 2024
1 parent 9ecd5d5 commit 00507bb
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 41 deletions.
90 changes: 90 additions & 0 deletions host-app/components/useFederatedComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { init, loadRemote } from "@module-federation/runtime";
import React from "react";

init({
name: "host",
remotes: [
{
name: "remote",
entry: "http://localhost:3000/MFRemote/remote.js",
},
],
});

function loadComponent(scope, module) {
return async () => {
// Initializes the share scope. This fills it with known provided modules from this build and all remotes
const Module = await loadRemote(`${scope}/${module.slice(2)}`);
return Module;
};
}

const urlCache = new Set();
const useDynamicScript = (url) => {
const [ready, setReady] = React.useState(false);
const [errorLoading, setErrorLoading] = React.useState(false);

React.useEffect(() => {
if (!url) return;

if (urlCache.has(url)) {
setReady(true);
setErrorLoading(false);
return;
}

setReady(false);
setErrorLoading(false);

const element = document.createElement("script");

element.src = url;
element.type = "text/javascript";
element.async = true;

element.onload = () => {
urlCache.add(url);
setReady(true);
};

element.onerror = () => {
setReady(false);
setErrorLoading(true);
};

document.head.appendChild(element);

return () => {
urlCache.delete(url);
document.head.removeChild(element);
};
}, [url]);

return {
errorLoading,
ready,
};
};

const componentCache = new Map();
export const useFederatedComponent = (remoteUrl, scope, module) => {
const key = `${remoteUrl}-${scope}-${module}`;
const [Component, setComponent] = React.useState(null);

const { ready, errorLoading } = useDynamicScript(remoteUrl);
React.useEffect(() => {
if (Component) setComponent(null);
// Only recalculate when key changes
}, [key]);

React.useEffect(() => {
if (ready && !Component) {
const Comp = React.lazy(loadComponent(scope, module));
componentCache.set(key, Comp);
setComponent(Comp);
}
// key includes all dependencies (scope/module)
}, [Component, ready, key]);

return { errorLoading, Component };
};
3 changes: 2 additions & 1 deletion host-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"lint": "next lint"
},
"dependencies": {
"@module-federation/nextjs-mf": "8.1.3",
"@module-federation/nextjs-mf": "8.1.5",
"@module-federation/runtime": "^0.0.8",
"@module-federation/utilities": "3.0.5",
"@stitches/react": "^1.2.8",
"next": "^13.0.7",
Expand Down
26 changes: 6 additions & 20 deletions host-app/pages/index.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
import { importRemote } from "@module-federation/utilities";
import { lazy, useEffect, useState } from "react";
import Button from "../components/Button";
import { useFederatedComponent } from "../components/useFederatedComponent";

export default function Home() {
const [Component, setComponent] = useState(null);
const module = "./Button";
const scope = "remote";
const url = "http://localhost:3000/MFRemote/remote.js";
const { Component, errorLoading } = useFederatedComponent(url, scope, module);

const module = "Button";

useEffect(() => {
if (typeof window !== "undefined") {
setComponent(
lazy(
async () =>
await importRemote({
url: "http://localhost:3000/MFRemote",
scope: "remote",
remoteEntryFileName: "remote.js",
module: module,
})
)
);
}
}, []);
return (
<div style={{ padding: "2%" }}>
<h1>Next JS and React</h1>
<h2>Host - Button</h2>
<Button />
<h2>Client - Button</h2>
{errorLoading}
{Component && <Component />}
</div>
);
Expand Down
57 changes: 41 additions & 16 deletions host-app/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 0 additions & 4 deletions remote-app/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,9 @@ module.exports = {
},
react: {
singleton: true,
version: '0',
requiredVersion: false,
},
'react-dom': {
requiredVersion: false,
singleton: true,
version: '0',
},
},
}),
Expand Down

0 comments on commit 00507bb

Please sign in to comment.