Last active
October 14, 2025 06:53
-
-
Save anatooly/7dc2ebd4545bfec969aeb500cdc6da03 to your computer and use it in GitHub Desktop.
Micro frontend custom
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use client"; | |
| import MicroFrontendLoader from "../MicroFrontendLoader"; | |
| export const ExampleWidget = () => { | |
| const { theme } = useTheme(); | |
| const opts = { | |
| theme: ", | |
| userId: "", | |
| onCallGetUser: async () => { | |
| return { name: "" } | |
| }, | |
| }; | |
| return ( | |
| <MicroFrontendLoader | |
| url="http://localhost:3001/micro-app.js" | |
| componentName="ExampleApp" | |
| props={opts} | |
| /> | |
| ); | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use client"; | |
| import * as _jsxruntime from "react/jsx-runtime"; | |
| import React from "react"; | |
| import ReactDOM from "react-dom/client"; | |
| if (typeof window !== "undefined") { | |
| window.React = React; | |
| window.ReactDOM = ReactDOM; | |
| window.ReactJSXRuntime = _jsxruntime; | |
| } | |
| export default function JsxRuntimeProvider() { | |
| return null; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use client"; | |
| import { useEffect, useRef } from "react"; | |
| export default function MicroFrontendLoader({ | |
| url, | |
| componentName, | |
| props = {}, | |
| }) { | |
| const containerRef = useRef(null); | |
| useEffect(() => { | |
| if (!containerRef.current) return; | |
| let script = Array.from(document.scripts).find((s) => s.src === url); | |
| const mountComponent = () => { | |
| if (window.mountMicroComponent) { | |
| window.mountMicroComponent(containerRef.current, componentName, props); | |
| } | |
| }; | |
| if (script) { | |
| mountComponent(); | |
| return; | |
| } | |
| script = document.createElement("script"); | |
| script.src = url; | |
| script.async = true; | |
| script.onload = () => { | |
| mountComponent(); | |
| }; | |
| document.head.appendChild(script); | |
| }, [url, componentName, props]); | |
| return <div ref={containerRef} />; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export default function ExampleApp(props) { | |
| const { theme, userId, onCallGetUser } = props ?? {}; | |
| return null; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React from "react"; | |
| import ReactDOM from "react-dom/client"; | |
| import ExampleApp from "./components/ExampleApp"; | |
| if (import.meta.env.MODE === "development") { | |
| ReactDOM.createRoot(document.getElementById("root")).render(<App />); | |
| } else { | |
| const componentRegistry = { ExampleApp }; | |
| const mountedRoots = new Map(); | |
| window.mountMicroComponent = (container, componentName, props) => { | |
| const ComponentToRender = componentRegistry[componentName]; | |
| console.log({ container, componentName, props }); | |
| if (!container || !ComponentToRender) { | |
| console.error(`Component "${componentName}" not found.`); | |
| return; | |
| } | |
| const rootElement = ( | |
| <React.StrictMode> | |
| <ComponentToRender {...props} /> | |
| </React.StrictMode> | |
| ); | |
| if (mountedRoots.has(container)) { | |
| mountedRoots.get(container).render(rootElement); | |
| } else { | |
| const root = ReactDOM.createRoot(container); | |
| mountedRoots.set(container, root); | |
| root.render(rootElement); | |
| } | |
| }; | |
| window.unmountMicroComponent = (container) => { | |
| if (mountedRoots.has(container)) { | |
| mountedRoots.get(container).unmount(); | |
| mountedRoots.delete(container); | |
| } | |
| }; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { defineConfig } from "vite"; | |
| import react from "@vitejs/plugin-react"; | |
| export default defineConfig({ | |
| base: "http://localhost:3001/", | |
| plugins: [react()], | |
| build: { | |
| rollupOptions: { | |
| // Not include all React core lib in result build | |
| external: ["react", "react-dom/client", "react/jsx-runtime"], | |
| output: { | |
| globals: { | |
| react: "React", | |
| "react-dom/client": "ReactDOM", | |
| "react/jsx-runtime": "ReactJSXRuntime", | |
| }, | |
| format: "iife", | |
| entryFileNames: "micro-app.js", | |
| assetFileNames: `[name].[ext]`, | |
| }, | |
| }, | |
| }, | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment