├── .DS_Store ├── .gitignore ├── README.md ├── micro-client ├── babel.config.json ├── package-lock.json ├── package.json ├── public │ └── index.html ├── src │ ├── App.js │ ├── index.js │ └── styles.css └── webpack.config.js └── micro-host ├── babel.config.json ├── package-lock.json ├── package.json ├── public └── index.html ├── src ├── components │ ├── App.js │ ├── Main.js │ └── styles.css └── index.js └── webpack.config.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amit08255/react-microfrontend/7b797f97a6d3a05b5198f375d46fb265e0419619/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Microfrontend 2 | 3 | ## 1. Start host microfrontend 4 | 5 | The host contains the microfrontend app and client integrates the microfrontend. Run below commands to install dependencies and start host microfrontend. 6 | 7 | ```sh 8 | npm install 9 | npm start 10 | ``` 11 | 12 | The host server will start at port `8080`. Visiting http://localhost:8080/ will display the microfrontend app. 13 | 14 | ## 2. Start client microfrontend 15 | 16 | The client integrates the microfrontend app built in React. Run below commands to install dependencies and start client microfrontend. 17 | 18 | ```sh 19 | npm install 20 | npm start 21 | ``` 22 | 23 | The client server will start at port `8081`. Visiting http://localhost:8081/ will display the React app with microfrontend integrated inside it. 24 | -------------------------------------------------------------------------------- /micro-client/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ] 6 | } -------------------------------------------------------------------------------- /micro-client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "micro-host", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack", 8 | "start": "webpack serve --watch-files ./src" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.21.0", 19 | "@babel/preset-env": "^7.20.2", 20 | "@babel/preset-react": "^7.18.6", 21 | "babel-loader": "^9.1.2", 22 | "css-loader": "^6.7.3", 23 | "html-webpack-plugin": "^5.5.0", 24 | "sass": "^1.58.3", 25 | "sass-loader": "^13.2.0", 26 | "style-loader": "^3.3.1", 27 | "webpack": "^5.75.0", 28 | "webpack-cli": "^5.0.1", 29 | "webpack-dev-server": "^4.11.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /micro-client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Micro App 6 | 7 | 8 |
9 | 10 | -------------------------------------------------------------------------------- /micro-client/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { lazy, Suspense } from "react"; 2 | import "./styles.css"; 3 | 4 | const FirstApp = lazy(() => import("FIRST_APP/app")); 5 | 6 | const App = () => { 7 | const [name, setName] = React.useState(null); 8 | 9 | return ( 10 |
11 |

This is second app

12 |

Micro host app is integrated here

13 | { name ?

Your name is: {name}

: null } 14 |
15 | Loading...}> 16 | setName(e.target.value)} /> 17 | 18 |
19 |
20 | ); 21 | }; 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /micro-client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StrictMode } from "react"; 3 | import { createRoot } from "react-dom/client"; 4 | 5 | import App from "./App"; 6 | 7 | const rootElement = document.getElementById("container"); 8 | const root = createRoot(rootElement); 9 | 10 | root.render( 11 | 12 | 13 | 14 | ); 15 | -------------------------------------------------------------------------------- /micro-client/src/styles.css: -------------------------------------------------------------------------------- 1 | .App { 2 | font-family: sans-serif; 3 | text-align: center; 4 | } 5 | -------------------------------------------------------------------------------- /micro-client/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 2 | const path = require("path"); 3 | const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); 4 | const deps = require("./package.json").dependencies; 5 | 6 | module.exports = { 7 | mode: "development", 8 | resolve: { 9 | extensions: [".css", ".scss", ".js", ".jsx"], 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.s?css$/, 15 | use: [ 16 | "style-loader", 17 | { 18 | loader: "css-loader", 19 | options: { 20 | url: { 21 | filter: (url) => { 22 | if (url.startsWith("data:")) { 23 | return false; 24 | } 25 | return true; 26 | }, 27 | }, 28 | }, 29 | }, 30 | "sass-loader", 31 | ], 32 | }, 33 | { 34 | test: /\.jsx?$/, 35 | use: ["babel-loader"], 36 | exclude: /node_modules/, 37 | }, 38 | ], 39 | }, 40 | plugins: [ 41 | new HtmlWebpackPlugin({ 42 | template: path.resolve(__dirname, "public", "index.html"), 43 | }), 44 | new ModuleFederationPlugin({ 45 | name: "MICRO", 46 | remotes: { 47 | FIRST_APP: "FIRST_APP@http://localhost:8080/remoteEntry.js", 48 | }, 49 | }), 50 | ], 51 | }; -------------------------------------------------------------------------------- /micro-host/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ] 6 | } -------------------------------------------------------------------------------- /micro-host/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "micro-host", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack", 8 | "start": "webpack serve --watch-files ./src" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.21.0", 19 | "@babel/preset-env": "^7.20.2", 20 | "@babel/preset-react": "^7.18.6", 21 | "babel-loader": "^9.1.2", 22 | "css-loader": "^6.7.3", 23 | "html-webpack-plugin": "^5.5.0", 24 | "sass": "^1.58.3", 25 | "sass-loader": "^13.2.0", 26 | "style-loader": "^3.3.1", 27 | "webpack": "^5.75.0", 28 | "webpack-cli": "^5.0.1", 29 | "webpack-dev-server": "^4.11.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /micro-host/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Micro App 6 | 7 | 8 |
9 | 10 | -------------------------------------------------------------------------------- /micro-host/src/components/App.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import "./styles.css"; 3 | 4 | export default function App({ onChange }) { 5 | return ( 6 |
7 |

Micro App

8 | 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /micro-host/src/components/Main.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import App from './App'; 3 | import "./styles.css"; 4 | 5 | export default function MainApp() { 6 | const [name, setName] = React.useState(null); 7 | return ( 8 | <> 9 |

{ name ?

Your name is: {name}

: null }

10 | setName(e.target.value)} /> 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /micro-host/src/components/styles.css: -------------------------------------------------------------------------------- 1 | .MicroApp { 2 | box-sizing: border-box; 3 | margin: auto; 4 | margin-top: 100px; 5 | padding: 30px; 6 | width: 95%; 7 | border: 2px solid black; 8 | border-radius: 12px; 9 | font-family: sans-serif; 10 | text-align: center; 11 | } 12 | 13 | .MicroApp input { 14 | height: 32px; 15 | border-radius: 8px; 16 | border: 2px solid gray; 17 | width: 350px; 18 | padding-left: 10px; 19 | padding-right: 10px; 20 | } -------------------------------------------------------------------------------- /micro-host/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StrictMode } from "react"; 3 | import { createRoot } from "react-dom/client"; 4 | import MainApp from './components/Main'; 5 | 6 | const rootElement = document.getElementById("container"); 7 | const root = createRoot(rootElement); 8 | 9 | root.render( 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /micro-host/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 2 | const path = require("path"); 3 | const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); 4 | const deps = require("./package.json").dependencies; 5 | 6 | module.exports = { 7 | mode: "development", 8 | resolve: { 9 | extensions: [".css", ".scss", ".js", ".jsx"], 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.s?css$/, 15 | use: [ 16 | "style-loader", 17 | { 18 | loader: "css-loader", 19 | options: { 20 | url: { 21 | filter: (url) => { 22 | if (url.startsWith("data:")) { 23 | return false; 24 | } 25 | return true; 26 | }, 27 | }, 28 | }, 29 | }, 30 | "sass-loader", 31 | ], 32 | }, 33 | { 34 | test: /\.jsx?$/, 35 | use: ["babel-loader"], 36 | exclude: /node_modules/, 37 | }, 38 | { 39 | test: /\.(png|svg|jpg|jpeg|gif)$/i, 40 | type: "asset/resource", 41 | }, 42 | ], 43 | }, 44 | plugins: [ 45 | new HtmlWebpackPlugin({ 46 | template: path.resolve(__dirname, "public", "index.html"), 47 | }), 48 | new ModuleFederationPlugin({ 49 | name: "FIRST_APP", 50 | filename: "remoteEntry.js", 51 | exposes: { 52 | "./app": "./src/components/App", 53 | }, 54 | }), 55 | ], 56 | }; --------------------------------------------------------------------------------