Plugin to make micro frontend using create react app
Tags: javascript, react, webdev, programming
Published: 2021-12-26 07:36:55


Hello everyone, I got inspired by how micro service works on backend and helps scale, manage and brings flexibility to develop apps. So i created a plugin that would help frontend to use micro apps.


### This blog is divided into three parts:

1. Why did I create the plugin - The Purpose.
2. What's micro-frontend. - The thing.
3. How to use it. - Getting started.

---

### The purpose :sparkles: ?

> Convert your CRA project into a node library without ejecting or losing update support of react-scripts...

**Ummmm.. that sounds interesting.. but why ?**

Well, my apps were used as a **single page app** in a _WebView_ and also as **node package** 📦 in a _react app_.
I was using **ejected [create-react-app](https://create-react-app.dev/)**. For which I had to customize [webpack](https://webpack.js.org/) as a tool to build app for SPA and as a library.

So far it was working fine, until apps grew... it was harder to manage and with time I have to keep updating the ejected cra dependencies and update webpack config for all the apps.. which is not a good practice and requires more resources to do it...

So after research, found two best ways to do it

- **[craco](https://github.com/gsoft-inc/craco[](url))**  _we chose this option_
- [vite](https://vitejs.dev/)

However, there are pros and cons for choosing each, such as with *craco* comes with its amazing loader and plugins and provide extensive community due to vast ecosystem of *webpack* and CRA.. etc
*vite* is using _esbuild_ and is quite fast and less in size as compare to _webpack_... etc

---

### The thing :dart:

Micro-frontend are a new pattern where web application UIs (frontends) are composed from semi-independent fragments that can be built by different teams same or using different technologies. 

Benefits of Micro Frontend Architecture

- Separation automation of CI/CD pipeline
- Team flexibility
- Single responsibility
- Reusability
- Technology agnosticism: Micro Frontend architecture is independent of technology. You can use components from different web development frameworks (React, Vue, Angular, etc.)
- Simple learning (Smaller modules are easier to learn and understand)

---

### Getting started :the_horns::skin-tone-4:

**[Craco](https://github.com/gsoft-inc/craco)** is a api that overrides CRA and allowes to configure it. So using it I create a plugin called [craco-plugin-micro-frontend](https://www.npmjs.com/package/craco-plugin-micro-frontend) that would build ours apps.

Install it:
```bash
npm install craco-plugin-micro-frontend --save-dev
```

Use the plugin into your `craco.config.js` as below:
```js
const microFrontedPlugin = require('craco-plugin-micro-frontend');

module.exports = {
  plugins: [
    {
      plugin: microFrontedPlugin,
      options: {
        orgName: 'my-org',
        fileName: 'my-app.js', // should same as package main
        entry: 'src/index.injectable.js', //defaults to src/index.injectable.js,
        orgPackagesAsExternal: false, // defaults to false. marks packages that has @my-org prefix as external so they are not included in the bundle
        reactPackagesAsExternal: true, // defaults to true. marks react and react-dom as external so they are not included in the bundle
        externals: ['react-router', 'react-router-dom'], // defaults to []. marks the specified modules as external so they are not included in the bundle
        minimize: true, // defaults to false, sets optimization.minimize value
        libraryTarget: 'commonjs2', // defaults to umd
        outputPath: 'dist',
        customJestConfig: {}, // custom jest configurations
      },
    },
  ],
};
```

NOTE: `src/index.injectable.js` is a wrapper around the react App file so that it would be separated from `src/index.js`: 

```js
import App from './App';

export default App;
```

Update the `package.json` scripts section of your app as follows:
```json
  ...
  "main": "my-app.js",
  "files": [
    "dist/**"
  ],
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "build:lib": "REACT_APP_INJECTABLE=true craco build",
    "test": "craco test",
    "coverage": "npm run test -- --coverage --watchAll=false --passWithNoTests",
    "coverage:browser": "npm run coverage && open coverage/lcov-report/index.html",
    "analyze": "REACT_APP_INTERACTIVE_ANALYZE=true npm run build",
```
---

### Conclusion
This plugin helped me manage the build process and made my life easier.. Now that [CRA](https://github.com/facebook/create-react-app) new version is release to [v5](https://github.com/facebook/create-react-app/releases/tag/v5.0.0) all I have to to do is update dependencies of [craco-plugin-micro-frontend](https://github.com/m-nathani/craco-plugin-micro-frontend) and it would update `react-scripts` to v5, thus all my app will upgraded too.

~~P.S: [craco-plugin-micro-frontend](https://www.npmjs.com/package/craco-plugin-micro-frontend) is waiting for @craco to update its peer deps to `react-script: "5.0.0"` Further information at: [craco-issue](https://github.com/gsoft-inc/craco/issues/353)~~

#### NOTE
[craco-plugin-micro-frontend](https://www.npmjs.com/package/craco-plugin-micro-frontend) now fully supports `react-script: "5.0.0"` :partying_face: 

---
Here is the repo for the [demo](https://github.com/m-nathani/react-bootstrap)

Thats it, thanks!

{% link https://dev.to/mnathani/how-to-cache-frontend-app-1kkj %}