Build Web Component with React and use it in an Angular app
In this article, I use react-to-webcomponent
to package a React app as a web-component and use it as a micro frontend in an Angular app.
Here’s what we create in this article:
The react application is very basic to show a list of string by using Material UI. To show how to pass data from another app, the list is provided as props from an angular app. While angular app is sending data and provide search functionality and also reusing web-component to show the list.
It’s not possible to show all the code here but if you want to follow along use the code here: Example code of React and Example code of Angular .
Steps to convert React component to custom element
- After creating a react app, add
react-to-webcomponent
library:
yarn add react-to-webcomponent
2. Import react-to-webcomponent
into index.js
and use the reactToWebComponent
function exported from the module to create a web-component and then register that component. The code is shown below:
import reactToWebComponent from "react-to-webcomponent";const app = reactToWebComponent(App, React, ReactDOM);
customElements.define("app-webcomponent", app);
3. Build the app by running yarn build
and then you can use new html tag <app-webcomponent></app-webcomponent>
in another website by adding a script tag that points to the file created by the build script.
Host the build files locally
You can follow the following steps to server the static files for test purposes.
1. I have used the following script to merge the build files into one single file with name main.js
.
#!/usr/bin/env nodeconst { readFile } = require("fs").promises;
const concat = require("concat");(async function build() {
try {
const assetManifestPath = "./build/asset-manifest.json";
const { entrypoints } = JSON.parse(
await readFile(assetManifestPath, "utf8")
);
const filePaths = entrypoints
.filter((path) => /\.js$/.test(path))
.map((path) => `./build/${path}`);
const outFile = "./build/main.js";
await concat(filePaths, outFile);
console.log(
`Concatenated the following files into ${outFile}\n\n${filePaths.join("\n")}`
);
} catch (error) {
console.error(error);
}
})();
2. You need to update your build script inside package.json
file.
"build": "react-scripts build && ./concatBuiltJs.js"
3. Install http-server
if it is not already installed on you machine.
yarn global add http-server
4. Run the following command from your project to serve build files
http-server -p 4202 build
Use web-component in an Angular app
- Create a basic angular app using
ng new angular-app
- Add
local-proxy.config.json
file to target build files. Remember to keep the same port in config file as you did while runninghttp-server
{
"/micro-frontend/main.js": {
"target": "http://localhost:4202",
"secure": false,
"logLevel": "debug",
"changeOrigin": true,
"pathRewrite": {"^/micro-frontend" : ""}
}
}
3. Add script tag inside index.html
file in your angular app to point to your build file.
<script type="text/javascript" src="/micro-frontend/main.js"></script>
4. Now you can use the new html tag of your web-component and provide the correct input/ props.
<app-webcomponent [data]="data"></app-webcomponent>private readonly data = [
"Fantastic Plastic Shoes",
"Fantastic Steel Car",
"Licensed Steel Gloves",
"Rustic Wooden Hat",
"Handmade Granite Chicken",
"Generic Rubber Sausages",
"Refined Granite Shoes",
"Rustic Wooden Computer",
"Licensed Rubber Chair",
"Refined Granite Car"
];
Success 🚀 We have achieved what we wanted! 🎉
Please let me know your feedback via 👏 or 📝