Est. reading time: 6 minutes
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.
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:
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 🙂
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 postcssnpm 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 storybookmodule.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'), ], }, }, }, ], },};
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
.