- Notifications
You must be signed in to change notification settings - Fork16
Micro Front-end react apps created by Create-React-App, Connect multiple react apps to single parent app.
License
NotificationsYou must be signed in to change notification settings
miteshtagadiya/microfrontend-react
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Micro Front-end react apps created by Create-React-App
Micro-frontend architecture is a design approach in which a front-end app is decomposed into individual, semi-independent “microapps” working loosely together.
Th applications are loaded into a micro-frontend container. The container runs it as of the micro frontend is its own component and provides seamless workflow to users.
- Launch container app.
- Launch sub-app1 and sub-app2 applications on specific ports.
- Based on the URL, the Container will route to one of the micro front-ends.
- The selected micro front-end goes to the specific port to fetch the application’s asset-manifest.json. From this JSON file, the included main.js is put on a script tag and loaded.
- A manifest file contains a mapping of all asset filenames.
- Container app passes the containerId and history for its micro front-ends to be rendered.
- Install "react-app-rewired" — This allows customizing the app without ejecting app.
npmi--savereact-app-rewired
- Modify package.json to set port and use "react-app-rewired" in sub-apps.
"scripts":{"start":"PORT=4001 react-app-rewired start","build":"react-app-rewired build","test":"react-app-rewired test","eject":"react-app-rewired eject"},
- Add config-overrides.js to disable code splitting. By default, code splitting is enabled. An application is split into several chunks that can be loaded onto the page independently. You can seehttp://localhost:4001/asset-manifest.json before adding react-app-rewired. It clearly shows the app has been chunked.
//config-overrides.jsmodule.exports={webpack:(config,env)=>{config.optimization.runtimeChunk=false;config.optimization.splitChunks={cacheGroups:{default:false,},};returnconfig;},};
- Make changes in src/index.js to define render and unmount functions.
importReactfrom"react";importReactDOMfrom"react-dom";import"./index.css";importAppfrom"./App";import*asserviceWorkerfrom"./serviceWorker";// render micro frontend functionwindow.rendersubapp1=(containerId,history)=>{ReactDOM.render(<Apphistory={history}/>,document.getElementById(containerId));serviceWorker.unregister();};// unmount micro frontend functionwindow.unmountsubapp1=containerId=>{ReactDOM.unmountComponentAtNode(document.getElementById(containerId));};// Mount to root if it is not a micro frontendif(!document.getElementById("subapp1-container")){ReactDOM.render(<App/>,document.getElementById("root"));}// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://bit.ly/CRA-PWAserviceWorker.unregister();
- If an app is running independent, it will be rendered to root element. If it is a micro front-end, it will be rendered to containerId by window.rendersubapp1.
- Use src/setupProxy.js to set up CORS rule.
module.exports=app=>{app.use((req,res,next)=>{res.header('Access-Control-Allow-Origin','*');next();});};
- Configure Your .env File to Set Up a Host for Each Micro-Frontend Application in Container app.
REACT_APP_SUBAPP1_HOST=http://localhost:4001REACT_APP_SUBAPP2_HOST=http://localhost:4002
- Add Microfront.js file in sec directory, It picks up a manifest file from a running application and launches the application through a script and link tag.
importReactfrom'react';classMicroFrontendextendsReact.Component{componentDidMount(){const{ name, host, document}=this.props;constscriptId=`micro-frontend-script-${name}`;if(document.getElementById(scriptId)){this.renderMicroFrontend();return;}fetch(`${host}/asset-manifest.json`).then(res=>res.json()).then(manifest=>{manifest["entrypoints"].map((entry=>{if(typeofmanifest["files"][entry]!=="undefined"&&manifest["files"][entry]!=="undefined"){if(entry.endsWith('.css')){constlink=document.createElement('link');link.id=scriptId;link.href=`${process.env.NODE_ENV==="production" ?host.slice(0,host.lastIndexOf('/')) :host}${manifest["files"][entry]}`;link.onload=this.renderMicroFrontend;link.rel="stylesheet"document.head.appendChild(link);}constscript=document.createElement('script');script.id=scriptId;script.crossOrigin='';script.src=`${process.env.NODE_ENV==="production" ?host.slice(0,host.lastIndexOf('/')) :host}${manifest["files"][entry]}`;script.onload=this.renderMicroFrontend;document.head.appendChild(script);}}))constscript=document.createElement('script');script.id=scriptId;script.crossOrigin='';script.src=`${process.env.NODE_ENV==="production" ?host.slice(0,host.lastIndexOf('/')) :host}${manifest["files"]["main.js"]}`;script.onload=this.renderMicroFrontend;document.head.appendChild(script);constlink=document.createElement('link');link.id=scriptId;link.href=`${process.env.NODE_ENV==="production" ?host.slice(0,host.lastIndexOf('/')) :host}${manifest["files"]["main.css"]}`;link.onload=this.renderMicroFrontend;link.rel="stylesheet"document.head.appendChild(link);});}componentWillUnmount(){const{ name, window}=this.props;window[`unmount${name}`]&&window[`unmount${name}`](`${name}-container`);}renderMicroFrontend=()=>{const{ name, window, history}=this.props;window[`render${name}`]&&window[`render${name}`](`${name}-container`,history);};render(){return<mainid={`${this.props.name}-container`}/>;}}MicroFrontend.defaultProps={ document, window,};exportdefaultMicroFrontend;
- In Container App Create a Micro-Frontend Component for each micro-frontend application and Use a route to invoke it.
importReactfrom"react";import{NavLink,BrowserRouter,Route,Switch}from"react-router-dom";importMicroFrontendfrom"./MicroFrontend";const{REACT_APP_SUBAPP1_HOST:subapp1,REACT_APP_SUBAPP2_HOST:subapp2}=process.env;constSubApp2=({ history})=>(<MicroFrontendhistory={history}host={subapp2}name="subapp2"/>);constSubApp1=({ history})=>(<MicroFrontendhistory={history}host={subapp1}name="subapp1"/>);constHome=()=>(<><p>Rendered by Container</p></>);constApp=props=>{return(<BrowserRouter><divstyle={{padding:25,display:"flex"}}><divstyle={{padding:"0px 15px"}}><NavLinkstyle={{textDecoration:"none",fontWeight:"bold",color:"#282c34",fontSize:20}}to="/home"> Home</NavLink></div><divstyle={{padding:"0px 15px"}}><NavLinkstyle={{textDecoration:"none",fontWeight:"bold",color:"#282c34",fontSize:20}}to="/subapp1"> SubApp1</NavLink></div><divstyle={{padding:"0px 15px"}}><NavLinkstyle={{textDecoration:"none",fontWeight:"bold",color:"#282c34",fontSize:20}}to="/subapp2"> SubApp2</NavLink></div></div><Switch><Routepath="/home"component={Home}/><Routepath="/subapp1"render={()=><SubApp1/>}/><Routepath="/subapp2"render={()=><SubApp2/>}/></Switch></BrowserRouter>);};exportdefaultApp;
ContainerApp: http://localhost:3000SubApp1: http://localhost:4001SubApp2: http://localhost:4002
About
Micro Front-end react apps created by Create-React-App, Connect multiple react apps to single parent app.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
No releases published
Packages0
No packages published
Uh oh!
There was an error while loading.Please reload this page.
