Plugin to make micro frontend using CRA

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 ?

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. For which I had to customize webpack 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

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

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

Craco is a api that overrides CRA and allowes to configure it. So using it I create a plugin called craco-plugin-micro-frontend that would build ours apps.

Install it:

npm install craco-plugin-micro-frontend --save-dev

Use the plugin into your craco.config.js as below:

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: false, // 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:

import App from './App';

export default App;

Update the package.json scripts section of your app as follows:

...
  "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 new version is release to v5 all I have to to do is update dependencies of 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 is waiting for @craco to update its peer deps to react-script: "5.0.0" Further information at: craco-issue

Here is the repo for the demo
Thats it, thanks!

16