Tailwind CSS + Module Federation
How to use Tailwind CSS in an Angular Microfrontend
Tailwind CSS is a modern CSS utility library used by thousands of people. It allows to use predefined css classes directly inside the html such that creating custom css classes is rarely needed. But setting it up for a microfrontend is a bit tricky. Anyway, don't worry, in this article you will learn how to setup an Nx workspace with module federation and use Tailwind CSS in the microfrontend.
Tailwind in a Nutshell
Tailwind CSS is all about making styling web applications easier. Instead of having to come up with CSS class names, which actually is a really difficult task, you can use Tailwind CSS and add lots of predefined utility classes to the class attribute inside your html templates. Although, it is often debated if Tailwind is counter-productive because it clutters the html template, I made the personal experience that I was a lot faster using it. The biggest advantage is that you do not have to think about good telling css class names and that is a huge win for Tailwind.
Setting up Module Federation
In case you are not so familiarwith microfrontends and module federation yet, I would recommend reading this article I wrote a while a go which is tailored for module federation beginners.
Getting started with Module Federation
In this article I have created an Nx workspace containing two applications (shell, remote) with the standalone API. Hence, a routing configuration is exposed by the microfrontend instead of the usual ngModule. But that is just because routes can be officialy lazy loaded since Angular 15.
Adding Tailwind
First of all, we need to install Tailwind.
Running the following command will install the necessary packages (
tailwindcss,
postcss,
autoprefixer).
npm install tailwindcss
npx nx generate @nrwl/angular:setup-tailwind [remoteName]
@tailwind base;
@tailwind components;
@tailwind utilities;
/* You can add global styles to this file, and also import other style files */
Proxy Pattern
In order to also share the tailwind styles during module federation, we have to include tailwind imports in the styles of each component that the microfrontend uses. Well yes, but there is a better way where we can just import tailwind once. We can use a ProxyComponent that is simply wrapping the entire microfrontend that usually would be exposed in the webpack config and expose this proxy instead. Now we can put the tailwind imports into the styles of this proxy component. The last thing that has to be done is to set the ViewEncapsulation of the proxy component to None. This is because usually Angular would encapsulate all styles by default by obfuscating css classes. This is prevented and therefore the styles of this component act like a global stylesheet for all the child components and other components without view encapsulation. So be aware, that you should only put the tailwind imports in there to be on the safe side.
@tailwind base;
@tailwind components;
@tailwind utilities;
<router-outlet></router-outlet>
import { Component, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'tailwind-microfrontends-proxy',
standalone: true,
imports: [CommonModule, RouterOutlet],
templateUrl: './proxy.component.html',
styleUrls: ['./proxy.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ProxyComponent {}
import { Route } from '@angular/router';
export const routes: Route[] = [
{
path: '',
loadComponent: async () =>
(await import('./proxy.component')).ProxyComponent,
loadChildren: async () =>
(await import('@tailwind-microfrontends/remote-lib')).routes,
},
];