It’s Dec 2021 already and I’m curious about how micro-frontend implementation is going so far. This series of articles shows how it’s done for:
- AngularJS / Angular 4+ app (host) that uses a React component as a dependency
- Webpack 5 Module Federation example with nested React apps
- Webpack 5 Module Federation example with Angular contains React
AngularJS contains React
This is a very common case because AngularJS has been using for many legacy apps. The apps grow with the demand for splitting monolithic AngularJS implementation to micro-frontend with modern React components.
I won’t discuss this implementation in detail because there are many tools and articles already. The most common tool is ngReact, the repo is achieved already but it mentions some alternatives: react2angular, angular2react, and ngimport. These are also quite old (>3 years ago). Here are some examples:
Maybe I’ll get back and try implementing this case, but let’s go with the latest frameworks for now.
Angular 13 contains React 17
Giving a simple React Counter
component:
Note that counter
and onIncrease
will be bound from the parent app.
To render this component inside an Angular app, the solution is to wrap it inside another Angular component. This is an example wrapper:
The idea is to (re-)render the React component using react-dom
in the Angular ngOnChanges
and ngAfterViewInit
lifecycle hooks. Hopefully, this could be done the same way in Vue or LitElement 😏.
For binding state, the Angular component state counter
can be bound directly to the React component.
For binding event, create a new Angular component method handleIncrease
that emits a custom event. The current Angular must bind to this
keyword of the method. More about “bind”.
This wrapper component is then can be used as a normal Angular component:
// app.module.ts
@NgModule({
declarations: [AppComponent, CounterWrapper],
...
})// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})export class AppComponent {
public counter = 678;
public handleOnChildClick(stateCounter: number) {
this.counter++;
}
}// app.component.html
<react-counter
[counter]="counter"
(onIncrease)="handleOnChildClick($event)">
</react-counter>
Note: For Typescript JSX/TSX support, add "jsx": "react"
totsconfig.json
of the Angular project. For Angular 13, it is"jsx": "react-jsx"
.