React + TypeScript + Webpack + Module Federation Plugin - MicroFrontend Application
Harish Soni
Posted on December 16, 2022
Hello DEV,
Let's get to the point straight, I am writing this to learn and build a MicroFrontend Application using React + TS.
We will be using the below npm packages:
- React.js
- TypeScript
- Webpack - Module Federation Plugin.
- create-mf-app (https://www.npmjs.com/package/create-mf-app)
So if you are here, searching for a microfrontend using React.js, then I assume you already know what is React and how does it works with TypeScript.
So let's do it step by step:
Steps:
- To know about what is module federation plugin?
- How it helps in creating a microfrontend application.
- What we need to configure to make the core app, import from the other services which are running on the different PORTS.
- How to write export and import component on the one go?
Step 1::
According to Google:
Module Federation is one of the most exciting features in Webpack 5 and is considered a game-changer in JavaScript architecture. It supports more independent and straightforward code sharing at runtime among JavaScript applications, making the applications more adaptive and dynamic.
Step 2::
So we have configuration in the Module Federation which we use to connect the different application on a single container and access those application according to the concerns.
Step 3::
Below is the least example how how we export and import the components from the different application:
new ModuleFederationPlugin({
name: "home", // Application Name to use
filename: "homeEntry.js", // Filename to use when we remote this application from other app.
remotes: {
},
exposes: {
"./Home": "./src/Components.tsx" // Components to export/expose
},
shared: {
...deps,
react: {
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
singleton: true,
requiredVersion: deps["react-dom"],
},
},
}),
So let's learn the things one by one.
name - This is a unique value which we will use when we will import/remote this application on other application let's call this as container?
filename - It will be the bundled filename which will be loaded when the container application is loaded, as part of the page, and provides the exposed/exported code.
remotes - This is the part where in the application, we import the code from other application, the basic syntax for this is
{nameOfTheRemoteApplication}@http://{urlOfthe RunningApp}/{fileNameProvidedInWebpackOfTheRemoteApp}.js
login@http://localhost:3003/loginEntry.js
login: the Login Application where the name is provided as login.
http://localhost:3003: The URL of the Remote App running, with the PORT For local development
remoteEntry.js: The fileName which is provided in the remote application.
Below if how the Login Application webpack.config.js would look like.
new ModuleFederationPlugin({
name: "login",
filename: "loginEntry.js",
remotes: {
},
exposes: {
'./Login': './src/ExportedComponents.tsx'
},
shared: {
...deps,
react: {
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
singleton: true,
requiredVersion: deps["react-dom"],
},
},
}),
Step 4::
Once the application is created and the setup is done, we move to create the ExportedComponents.tsx file, for explaining simple here is what I have in my ExportedComponents.tsx
import React from 'react'
const LoginMain = () => {
return <div> New Deployment</div>
}
const LoginHome = () => {
return <div>The new era is coming here </div>
}
export {
LoginHome,
LoginMain
}
NOTE: HERE WE CANNOT EXPORT THE COMPONENT AS DEFAULT.
Named export would work for us, now let's use this LoginHome and LoginMain in our container application:
here is how the container/webpack.config.js would look like
new ModuleFederationPlugin({
name: "container", // Current App name
filename: "remoteEntry.js", // filename
remotes: { // the micro frontends to use in container the things which we want import from other service.
login: 'login@http://localhost:3003/loginEntry.js', },
exposes: {}, // to give components to other services
shared: {
...deps,
react: {
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
singleton: true,
requiredVersion: deps["react-dom"],
},
},
}),
You can learn what is shared in this config on the ModuleFederationPlugin docs.
Now let's move to importing the component, the syntax will be:
import { ComponentName } from 'NameOfTheApplication{from ModuleFederationPlugin config of the remote app}/KeyFromExposes{{from ModuleFederationPlugin config of the remote app}}'
example:
import { LoginMain, LoginHome } from 'login/Login'
Now this will simply render the component from the Login App.
Let's try creating a simple Micro Frontend Applllication.
- Create a container application using the below command:
npx create-mf-app container - Use PORT 3000
It will ask you some configs, do it accordingly.
- Create a simple Home App.
npx create-mf-app home Use PORT - 3001
- Create a Components.tsx file in Home/src/Components.tsx
Paste the below code:
import React from "react"
const HomePage = () => {
return <div>Homepage from the Home App</div>
}
export {
HomePage
}
- Open the home/webpack.config.js from the home app:
Replace the code for ModuleFederationPlugin
new ModuleFederationPlugin({
name: "home", // name
filename: "homeEntry.js",
remotes: {
},
exposes: {
"./Home": "./src/Components.tsx"
},
shared: {
...deps,
react: {
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
singleton: true,
requiredVersion: deps["react-dom"],
},
},
}),
- Open the container/webpack.config.js from the container app.
Replace the code for ModuleFederationPlugin
new ModuleFederationPlugin({
name: "container", // name
filename: "remoteEntry.js",
remotes: {
home: "home@http://localhost:3001/homeEntry.js"
},
exposes: {
},
shared: {
...deps,
react: {
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
singleton: true,
requiredVersion: deps["react-dom"],
},
},
})
- Open the App.tsx file from the container Application.
Add the import:
import { HomePage } from 'home/Home'
use as
Go to the container application folder, do yarn && yarn start
Go to the home application on the different tab of the terminal, do yarn && yarn start
Locate to http://localhost:3000
See if working if not add a comment with your doubt.
I have made a sample application here:
https://github.com/harish9312/microfrontend-example/tree/master
- Thanks
Posted on December 16, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
December 16, 2022