feature-image

Context

The evolving landscape of web development is embracing an innovative approach: integrating React components into Angular projects. This method is a testament to the versatility of micro frontend architecture, where diverse technologies coexist to enhance web applications.

In micro frontends, the application is divided into smaller, independent units, each potentially using different frameworks or libraries. This aligns perfectly with the concept of incorporating React components into Angular projects. React’s component-based approach, known for its efficient rendering and interactive UI capabilities, complements Angular’s structured and robust nature. By integrating React components, developers can leverage specific strengths of React, such as its dynamic UI construction, within the comprehensive framework that Angular offers.

A prime example of this integration in the context of micro frontends is Swagger UI. Built with React, Swagger UI demonstrates how React components can be smoothly integrated into Angular projects. This is particularly beneficial in environments where teams work with both React and Angular, facilitating a smoother transition between frameworks and promoting reuse of existing components.

This strategy not only underscores the flexibility of the micro frontend approach but also enhances the development process, leading to the creation of more responsive and user-friendly applications. It represents a strategic blend of Angular’s all-encompassing framework with the specialized UI prowess of React, optimizing both development experience and application performance.

In this blog, we’ll take a look at how to create and distribute a React component library and use the same in a Angular project.

Build & Distribute React component library:

First, we will create our project using the following command:

1
npx create-react-app sample-react-library

Next, we will install Babel by running the following commands:

1
2
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react
npm install @babel/cli

Why Babel?

Babel emerges as a pivotal tool in micro-frontend architectures for several reasons. When incorporating React components into Angular-based projects, developers often face challenges related to varying syntaxes and feature sets of these frameworks. Babel plays a crucial role here, providing a seamless way to transpile JSX used in React into JavaScript code that can be readily consumed by Angular. This not only ensures compatibility but also maintains performance and efficiency across different parts of the application.

Moreover, Babel’s extensive plugin ecosystem allows for fine-tuning the transpilation process. One can leverage these plugins to optimize the code for specific use cases, ensuring that the integrated React components perform optimally within the Angular environment. This adaptability is particularly beneficial in micro-frontend architectures where modular and independent deployment is key.

Additionally, Babel’s ability to compile the latest ECMAScript features into a more universally compatible format means developers can use the most modern JavaScript features in their React components without worrying about compatibility issues in the Angular host environment.

Babel Configuration:

The presets (@babel/preset-env and @babel/preset-react) are configurations for Babel that specify which transformations to apply.

Create the bundle.babel.js file in the root directory.

Importing Required Modules:

1
2
3
4
5
6
import path from "path";
import deepExtend from "deep-extend";
import webpack from "webpack";
import TerserPlugin from "terser-webpack-plugin";
import nodeExternals from "webpack-node-externals";
import { DuplicatesPlugin } from "inspectpack/plugin";
  • path: A built-in Node.js module that provides utilities for working with file and directory paths.
  • deepExtend: A module used for deeply merging JavaScript objects.
  • webpack: The core module for Webpack functionality.
  • TerserPlugin: A Webpack plugin for minification and optimization using Terser.
  • nodeExternals: A Webpack plugin for excluding node_modules from the bundle.
  • DuplicatesPlugin: A plugin from inspectpack that identifies duplicate dependencies in the bundle.

Custom Configuration:

The customConfig object is pivotal in fine-tuning the Webpack setup:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
export const customConfig = { 
  entry: { 
    "sample-library-bundle": ["./src/index.js"],
  },
  output: {
    globalObject: "this",
    library: {
      name: "sampleLibrary",
      export: "default",
    },
  },
  plugins: [
    new DuplicatesPlugin({
      emitErrors: false,
      verbose: false,
    }),
  ],
};
  • entry: Specifies the entry point(s) for bundling, such as “sample-library-bundle”: ["./src/index.js"].
  • output: Defines the characteristics of the bundled output, like the global object and library export.
  • plugins: Includes specific plugins; here, the DuplicatesPlugin is utilised to manage duplicate dependencies

Defining Base Rules:

The baseRules array outlines how various types of files should be treated during the bundling process:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
const baseRules = [
  {
    test: /\.jsx?$/,
    include: [
      path.join(projectBasePath, "src"),
      path.join(projectBasePath, "node_modules", "object-assign-deep"),
    ],
    loader: "babel-loader",
    options: {
      retainLines: true,
      cacheDirectory: true,
    },
  },
  { test: /\.(txt|yaml)$/, type: "asset/source" },
  {
    test: /\.(png|jpg|jpeg|gif|svg)$/,
    type: "asset/inline",
  },
];

Using the component lib in Angular:

Assuming we have a React component named SampleImport that handles dynamic content rendering, our goal is to seamlessly integrate it into an Angular project. Here’s how you can achieve this:

  1. Import SampleImport into Angular:

    Begin by importing the SampleImport component into your Angular project

    1
    2
    
    // Import SampleImport from the React component
    import { SampleImport } from "path-to-react-component";
    
  2. Configure SampleImport in Angular Component:

    Once imported, we can use SampleImport within an Angular component. Configure it with the desired settings, such as specifying the target HTML element using the dom_id parameter.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    import { Component, OnInit } from "@angular/core";
    import { SampleImport } from "path-to-react-component";
    
    @Component({
      selector: "app-angular-component",
      template: `
        <!-- Target HTML element for dynamic content rendering -->
        <div id="sampleId"></div>
      `,
    })
    export class AngularComponent implements OnInit {
      ngOnInit() {
        // Configure and use SampleImport
        SampleImport({
          dom_id: "#sampleId",
          // Additional configuration options, if any
        });
      }
    }
    

    In the Angular component’s template, we have a div with the ID sampleId, serving as the designated location for the dynamic content.

Conclusion

Blending of React and Angular through micro frontends is more than just a technical solution; it’s a paradigm shift in web development that promotes flexibility, efficiency, and a better end-user experience. As the web continues to evolve, such integrative approaches will likely become a mainstay, pushing the boundaries of what’s possible in web application development.