Micro Frontend using Angular
Create an Angular app
Ng new micro-header
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)
}
}
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')
})()
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"
Run : npm run bundle
This now creates this in dist:
dist > app > micro-header.js
Run “npm init” inside dist/app. This creates package.json file so that you can publish this as a library to npm
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"
}
Login to npm and then run “npm publish”
CONSUMING THE MICRO APP IN ANOTHER APPLICATION
Create an angular application: ng new consumer
npm i micro-header-test1@1.0.0
Include this in “scripts” of angular.json
Update “schemas” in app.module.ts
schemas: [CUSTOM_ELEMENTS_SCHEMA]
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
Post a Comment