Est. reading time: 6 minutes

Angular 11(+) and TailwindCSS 🎐

One of the main tools we're using to write content here Mimo is written using Angular. The styling is done using SASS and was great, up to the point where CSS was actually good enough so that you did not need all that SASS goodness anymore (e.g. variables). It also happened that a lot of duplicated styles accumulated over the years due to refactorings and multiple people working at the codebase - which, I believe, is unavoidable to a certain degree.

We have a cooldown week coming up and since I already gathered some experience with Tailwind in side projects and also this very page here, I discussed the switch with my fellow coders. A big plus - aside from removing all the issues mentioned above - is that we would be able to do it gradually and convert component after component to Tailwind.

What are the options? 🤔

After getting the green light to go ahead with my plan, I started to look around on how to get Angular and Tailwind to talk to each other. With a little help from my friend Google, I figured out that there are basically 2 ways for me to continue:

  • Using the schematics provided by ngneat/tailwind
  • Setting up the whole build pipeline by myself using PostCSS and a custom webpack config
  • waiting for Angular v11.2 to be released and use native Tailwind support

So here's the thing. For most people, the straightforward way of just using the schematics provided by the awesome team behind ngneat would probably be the way to go. When you look at their docs, you'll see it's nothing more than a simple install if you use Nx and even if you don't they got you covered as well.

But I really don't like installing separate libraries for everything. It has bitten me too many times, to be dependent on other people keeping the dependency alive and up to date, for things I could have easily done/achieved by myself. Don't get me wrong, I love OSS and the community and everything that came out of it but I feel like we're choosing the easy way of just installing a library for even the simplest things (cough leftpad coughcough ) a tiny bit too often 🤷‍♂️ To be clear here, that's just my personal opinion - you can install whatever and how much you like.

Also I could just wait for Angular v11.2 which is not released at the time of this writing. But I'm very impatient and the actual update from my way to the native way would probably make a good next blogpost 🙂

Doing it the "hard" way 🏋

Is it really the hard way, though? Let's look at what we actually have to do here. First of all we need some required dependencies (yeah, I know, kind of ironic right after the previous paragraph).

npm install tailwindcss postcss
npm install -D postcss-import postcss-loader@4.2.0 postcss-scss

The tailwindcss package should be self-explanatory and since Tailwind is basically just a postcss plugin, we need that too. The dev dependencies we install here are required for the build pipeline, we will see in a moment.

After the install is done we create a new tailwind.config.js at the root of our project.

module.exports = {
purge: ['./src/**/*.html', './src/**/*.ts'],
darkMode: false, // or 'media' or 'class'
theme: {},
variants: {},
plugins: [],
};

I did a bit of testing and I believe the following postcss config (also at project root) is technically not necessary. I only needed it because we're also using storybook in our project and without it, the styles did not get picked up. So check for yourself if you actually need it:

// NOTE: required for storybook
module.exports = {
plugins: {
'postcss-import': {},
tailwindcss: {},
autoprefixer: {},
},
};

Once that was done, we need to modify Angulars webpack config to introduce our custom postcss-loader. For this, we're using @angular-builders/custom-webpack which I believe was even recommended by the Angular team. (Note: I'm aware that this might go too far for some people but we are using this library for years now and never had any issues. Hopefully Angular provides its own way of extending/customizing the config soon). Follow the install guide and hook your custom webpack config up to the builder found in angular.json. All you have to do is replace the standard builder with the @angular-builders/custom-webpack:browser one and give it the path of your custom webpack config. Once this is done update the webpack config to include your postcss-loader with the custom plugins, we installed earlier.

module.exports = {
module: {
rules: [
{
test: /\.scss$/,
loader: 'postcss-loader',
options: {
postcssOptions: {
ident: 'postcss',
syntax: 'postcss-scss',
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
],
},
},
},
],
},
};

One style to rule them all 🎨

The final thing you need to do is include Tailwinds styles in the root styles.scss file

@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
/* probably some more styles here */

Once you've done this you can fire up the dev server and use Tailwinds utility classes in all your html and component files. Also purging should work once you set NODE_ENV to production. A repo that I also used as a reference can be found here. If you encounter any issues, just look at the files for guidance.

All in all the setup did not take that long, we installed no extra libraries apart from the ones that are actually needed by Tailwind and also the additional config was kept at a minimal level in my opinion. Again, using a custom webpack config with the help of an external library might be scary but it's unavoidable until Angular provides us with a way other than eject.