Building a MicroFrontend setup using Angular 12: Part 1 — The Project Setup

Jonathan Cardoz
6 min readJan 8, 2022

--

Photo by Xavi Cabrera on Unsplash

Disclaimer: This is my first set of articles on Medium and since I haven’t blogged or written anything (other than social media posts or restaurant reviews) for a couple of years, please bear with me. Comments are welcome.

I hope this set of articles helps you in understanding Micro Frontends (referred to as MFEs from now on), to setup your project and not make the same set of mistakes that my team and I did.

The other articles in the series are linked below

Pre-requisite reading: I would request you to read the following articles to cement your base on the topics we will cover in the series. You can also refer to this index of links to better understand a specific topic.

The project setup

Choosing Angular as the framework of choice:

TL;DR:

look at your specific requirement and then choose the framework that will support that the best

When choosing a framework, my team and I considered a number of factors. The main factor working in favor for Angular was that the framework worked well to scale and was designed to be used for larger projects. The client requirement involved building more than 30 different modules, so Angular seemed to be a good choice. While choosing Angular, we also checked feasibility of using Angular with Webpack 5 (Required for compatibility with the module federation plugin) and an MFE setup. Angular 11 offered support to Webpack 5 using a workaround approach, but when we upgraded to Angular 12, Webpack 5 was supported out of the box.

Thanks to the module federation plugin, we could use all of Angular CLI’s features along with MFE support. This meant we did not need to eject the project’s Webpack configuration file in order to modify the build process. So Angular worked well for us — as it offered both out-of-the-box MFE support and scalability. In addition, Angular CLI reduces the effort in setting up components, routes, modules and services, which is a pleasure to use.

This does not mean that Angular should be your choice when choosing a framework to use for your project. React, Vue or your favorite framework could be better suited to your requirement. Pick the one which works best for you and your team.

Using a monorepo

TL;DR:

Use a monorepo, when you need to have many different projects, but want to maintain a single source/place of truth for your code. Use CODEOWNER files to handle folder specific reviews.

The decision to go with a monorepo was one which was not taken lightly. I was initially skeptical about using a single repository for all our code, given that our codebase was going to become very large over time. Angular Workspace, which is specifically created for managing and working on multiple projects — worked well with the monorepo idea.

We kept our common components library in a separate repository and not within the monorepo so that other teams could import and use our components.

We also used a monorepo so that someone who wanted to contribute on any specific project would only need access to a single repository.

In order to avoid the downsides of a monorepo — such as different code reviewers for different projects, we used CODEOWNER files to setup specific people who were responsible for reviewing code for a specific project folder. They would be added as default reviewers to all PRs within that folder.

Using angular workspace

TL;DR:

If you want to look at the project structure, refer to the following link: sample workspace

As mentioned in the previous paragraph, an Angular workspace was perfect for our requirement. The setup provides you with separate folders for each of your projects, but a single package.json to handle your dependencies.

A Monorepo and an Angular workspace come together like peanut butter and jam — together they make a great sandwich!

As mentioned earlier, there is a single package.json file which holds dependencies for all of your projects. Note: If you create an angular library within your workspace, then this particular project type will have its own package.json file.

You might be wondering if a single package.jsonfile is a bad idea, as there may be dependencies used within one project, but not used in another. Rest assured, Webpack handles this using tree shaking and only adds those dependencies which a specific project requires.

The Angular workspace also allows you to run your commands for building, packaging and linting your individual projects from a single location. No switching folders — Since your package.json file is located at the root folder of your Angular Workspace, your commands work using this as the reference point. This is really convenient for development and also maintenance.

Using an Angular Library for common components

TL;DR:

If you want to look at the common component project structure, refer to the following link: sample library

As mentioned earlier, we created a separate component library using an Angular library. We also hosted the package in an internal NPM repository.

The purpose of doing this was two-fold: other projects could make use of the components within the library — as they did not contain any business logic and were simply dumb components, and that changes to the component library would not affect the monorepo setup.

Ideally, a separate team could work on the common component repository. In addition, using versioning allowed us to both use the common component library and update it without any MFE being affected.

Setting up your local workspace

From your terminal run the following command, in the folder where you plan to initialize your workspace

ng new sample-workspace --create-application false

Here sample-workspace will be the name of the angular workspace in which your files and subsequent projects and libraries will reside. This will be the root folder. Change the name to suite your project need. — create-application will not create any applications within your workspace.

Navigate into the folder using cd sample-workspace

You should see something like this in your sidebar, showing your project structure

Folder structure of the newly created angular workspace
folder structure

The projects folder is where your projects and libraries will reside, once you create them.

To add a new project to your workspace, use the ng generate CLI command

ng generate application app1

app1 indicates the name of the application I have created

Now, if you open the projects folder — you should see app1 within it

app1 within the projects folder
newly created apps will reside within the project folder

Similarly, to add a new library to your workspace, you use the ng generate command again

ng generate library lib1

lib1 indicates the name of the library I have created.

One thing that I did notice when using the CLI is that the build commands are limited. So you can create and add your own commands within the package.json file.

For instance, if you want to run the app1 created — add the following command to the scripts section of the package.json file.

"start:app1": "ng serve app1 -o --port 8080"

This will allow you to serve app1 on port 8080.

Save the file. You run yarn run start:app1 from your terminal to execute this command. Your app should open a new browser window with the default app loaded as seen below:

App1 preview shown in the browser

Similarly, if you want to build your library, add the following command

"build:lib1": "ng build lib1"

In case you are not able to run the app or you see an error, try running npm install or yarn to ensure your dependencies are installed correctly.

Now that you have your initial setup done, In Part 2 of the series, we will see how the different pieces fit and work together. We will also include the module federation plugin to get our MFE working.

Thank you for reading, and see you in the next one.

--

--