Disclaimer:
This is project is for education purpose only and was made to illustrate example of building microfrontend using Angular, Module Federation.
NOTE:
For version 14 with standalone components use 14.x branch
For version 13 without standalone components use 13.x branch
There is 1 host (shell) and 3 remote apps (watch-app, likes-app, history-app). Each app is deployed to different hosting storage.
There are 3 versions of source codes available:
π Turborepo (Current Repo)
πNx
πLerna
NOTE:
Server side rendering is implemented only on Lerna and Turborepo edition
β Multiple Angular applications on different domains
β Shared UI components and utils
β NgRx Store state management on each application
β Communication between angular applications
β Routing between applications
β Server Side Rendering
And others:
β Theming
β Keyboard shortcuts
My mission is to make complex microfrontend app as much as possible to have many cases for developers.
NOTE:
Hosted application is using Turborepo edition repo
Since workspaces are available from npm v7, you should have NodeJs 16+ installed.
1- Install turbo globally:
npm install turbo@1.2.8 -g
2- On root project install dependencies:
npm install
3- Start project and navigate to localhost:4200:
npm run serve
Or you can start in SSR mode:
npm run serve:ssr
Other commands: please see package.json
for other commands.
NOTE:
In case of error that components are not exported from youtube/common-ui, on project root run command npm run clean:cache
and then npm run serve
Here is my experience working with Lerna, Nx, and Turborepo. This can be inaccurate.
Lerna | Nx | Turborepo | |
---|---|---|---|
Library support | β
Both same and different versions of libraries (such as Angular, RxJs) |
β Monorepo only |
β Monorepo only |
Native (Angular CLI) | β | β Uses Nx CLI |
β |
Development efficiency | β Slow. Rebuild on any changes to common packages such as UI |
β
Very fast |
β |
Dependency graph | β No graph |
β
Powerful |
β |
Application configuration | β
|
β
|
β
|
To upgrade angular applications. Example:
On root:
npx @angular/cli@13 update @angular/core@13 @angular/cli@13 --force
On each remote app:
ng update @angular/core --migrate-only=true --from=13 --to=14
ng update @angular/cli --migrate-only=true --from=13 --to=14
1- Why I pass data via Input to remote apps?
The microfrontends apps(such as history or likes app) are NOT meant to be dependent on shell app.The reason I put inputs there is that I did not want to create additional Rest API for this(or signals such as socketjs) since I waslazy. Nevertheless, there are some cases where putting data via Input is very useful such as the current app state(ex: current playing videoId). For example, in my case, I deliberately inform Shell app from video-app that that I click on Like button(in real life we would do this via API of course). Sole purpose of this to provide example for communication between apps.So I strongly agree that remote apps should not be dependent on shell app for Data and the only reason I put Input is to give example how can we pass data to remotes which could be done without Signals(socketjs) APIs. The rest cases should be done via APIs.
Currently, the unit tests were not aded since the project was focused on main features such as module federation, managing state, intercommucation and so on. It can be started soon.
- Add I18n translations
- Add secondary entry points for common-ui
Want to contribute to improve community app? Looking forward for pull requests. Let's get started :)
Found repo useful? :) Let's star it β
Book: https://www.angulararchitects.io/en/book/
My blog: https://medium.com/p/258f331bc11e
Big thanks to https://github.com/manfredsteyer for his contribution for a lot of useful blogs + book for building microfrontend.
Xtreme Junior Front end developer focused on nice architecture and long term webapps.