Micro Frontend using Angular

WHY MICRO APP?
A whole angular application is bundled into a form that can simply be installed
and used anywhere else. It can even be used in a plain html page like below:

    <!DOCTYPE html>     <html>     <head>     <script src="https://cdn.jsdelivr.net/gh/Kavshree/micro-element-bundle/micro-header.js"></script>     </head>     <body> <micro-header></micro-header>     </body>     </html>

CREATING A MICRO APP

Let is start creating this app:
  1. Create an Angular app

Ng new micro-header


  1. app.module.ts

import { Injector, NgModule } from '@angular/core';

import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

import { createCustomElement } from '@angular/elements';

import { elementAt } from 'rxjs';


@NgModule({

  declarations: [

    AppComponent

  ],

  imports: [

    BrowserModule

  ],

  providers: [],

  //bootstrap: [AppComponent],

  entryComponents: [AppComponent]

})

export class AppModule {

  constructor(private injector: Injector) {}

  ngDoBootstrap() {

    const element  = createCustomElement(AppComponent, {injector: this.injector});

    customElements.define('micro-header', element)

  }

 }


  1. Create a bundle file in the root directory. This will take everything from “dist” and concatenate them into a single file as “micro-header.js”

const fs = require('fs-extra');

const concat = require('concat');


(async function build() {

    const files = [

        'dist/micro-header/main.js',

        'dist/micro-header/polyfills.js',

        'dist/micro-header/runtime.js',

        'dist/micro-header/styles.js',

    ]

    await fs.ensureDir('dist/app');

    await concat(files, 'dist/app/micro-header.js')

})()


  1. By default we will have styles.css. But this cannot be packaged into a single .JS file since it is in .css format.

Solution is to convert this into .js by using module bundler package like “style-loader” and “css-loader” provided by Webpack

  • RUN: npm install --save-dev style-loader css-loader webpack

  • Create webpack.config.js file

const path = require('path');

module.exports = {

  entry: './src/styles.css',

  output: {

    path: path.resolve(__dirname, 'dist/micro-header'),

    filename: 'styles.js'

  },

  module: {

    rules: [

      {

        test: /\.css$/,

        use: ['style-loader', 'css-loader']

      }

    ]

  }

};

  • Update a new script in “package.json”

"bundle": "webpack --mode production && node ./bundle.js"


  1. Run : npm run bundle

  2. This now creates this in dist:

dist > app > micro-header.js

  1. Run “npm init” inside dist/app. This creates package.json file so that you can publish this as a library to npm

  2. Not: You could make this step automated with a small script

{

  "name": "micro-header-test1",

  "version": "1.0.0",

  "description": "",

  "main": "micro-header.js",

  "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "author": "",

  "license": "ISC"

}



  1. Login to npm and then run “npm publish”



CONSUMING THE MICRO APP IN ANOTHER APPLICATION


  1. Create an angular application: ng new consumer

  2. npm i micro-header-test1@1.0.0

  3. Include this in “scripts” of angular.json

  1. Update “schemas” in app.module.ts

schemas: [CUSTOM_ELEMENTS_SCHEMA]

  1. In app.component.html

<micro-header></micro-header>


Output:



Note: All the styles in the main styles.css file from the micro app will get leaked into the other main

consuming app. So its a good practice to instead use app.component.css as the “main” style for the app

Also, make sure to use ViewEncapsulation.ShadowDom to make sure its not leaked anywhere else


Comments

Popular posts from this blog

Inside the JavaScript Memory Box: Visualizing Variables, References, and Copies

React & State Management: All Concepts

React: Communication between components