Angular 11 + Tailwindcss 2.0 = Blazing Fast 🔥
How to setup Tailwindcss 2.0 in an Angular 11 project
With the recent major release of Tailwindcss v2.0 and Angular v11 back in November 2020, it is really tempting to try it out in a project. However, setting up Tailwindcss to an Angular 11 project may be a bit tricky as it requires some additional webpack configs along with PostCSS plugins. On top of that, the official documentation (as of the time of this article’s writing) does not yet have the installation guide for Angular 11 framework. This article aims to provide a smooth integration of Tailwindcss 2.0 in an Angular 11 project along with other utility libraries that will help us achieve the goal.
Introduction: what is tailwindcss
As the name suggests, tailwind is a CSS framework that provides a different way of composing CSS. Normally, we would write CSS like the following:
We would create some CSS classes, divide them by their concerns, and write CSS codes specifically for each class. On the other hand, with tailwind, we would write like the following:
Yeah, that’s it. No CSS codes at all. We just need to call the pre-existing utility classes from tailwind and we’re good to go. There is a catch, though. Tailwind does not provide predefined component classes (e.g. .btn
, .card
, etc.) like Bootstrap or other CSS frameworks do. You may also wonder "what about maintainability and separation of concerns?". Unfortunately, we are not going to discuss that topic in this article, but the author of tailwind, Adam Wathan has a really great blog post that tells his own journey in which he went from writing "Semantic" CSS to Utility-first CSS. Hopefully by now, you have a rough idea about tailwind. Without further ado, let's get on with the guide!
Pre-requisites
Before proceeding to the guide, make sure you have the following installed in your operating system:
- Node.js
v12.13.0
or higher (as part of Tailwindcss v2.0 requirements) - Angular CLI
v11
Create an Angular 11 project
Using Angular CLI v11, create a new Angular 11 app with SCSS.
ng new angular11-tailwindcss --style=scss
cd angular11-tailwindcss
Install tailwindcss dependencies
First of all, install the latest tailwindcss
, postcss
, and autoprefixer
packages as devDependencies
:
npm i -D tailwindcss@latest postcss@latest autoprefixer@latest
Then, install a specific major version of postcss-import
, postcss-loader
, and postcss-scss
:
npm i -D postcss-import@12 postcss-loader@4 postcss-scss@3
Mind that installing the specific major version for
postcss-import@12
,postcss-loader@4
, andpostcss-scss@3
is important here as this is the configuration that works from my experience.
Configure an additional webpack config
After that, we’re going to install a 3rd party angular library via Angular Schematics called ngx-build-plus
, which is for extending the default webpack configs without the need to eject the angular app:
ng add ngx-build-plus
Make sure the installed
ngx-build-plus
version matches with the angular version. In our case, thengx-build-plus
version should be11.x.x
as we’re using Angular 11. If for some reasons the installed version does not match, use the specific version install commandng add ngx-build-plus@11
.
This command will install the ngx-build-plus
as dependencies in package.json
and automatically adjust the default angular.json
to be like the following:
Let’s now create a custom webpack config file called webpack.config.js
and place it in the root folder with the following configurations:
The above webpack config is mainly for setting up PostCSS. In this case, we’re using
postcss-import
,tailwindcss
, andautoprefixer
PostCSS plugins. To customise or learn more about other possible configurations, please visit https://tailwindcss.com/docs/using-with-preprocessors.
Now, we need to add an additional config to enable angular to read our additional webpack.config.js
file. Copy the following new line to angular.json
under "build"
, "serve"
, and "test"
options :
Make sure the property name is called
"extraWebpackConfig"
and the value matches your additional webpack config file name, which in our case should be"webpack.config.js"
. Additionally, ensure the additional webpack config file is placed in the root folder.
Configure and add tailwindcss
To start using tailwind in the project, let’s first generate a tailwindcss config file in the root folder using the command:
npx tailwindcss init
This will generate a file called tailwind.config.js
with the following generated configs:
The next step is to include tailwind styles in the global src/app/styles.scss
file, like so:
At this point, tailwind has been configured and it is ready to use!
Test out tailwind utility classes
Now, let’s make a simple page using tailwind utility classes to test whether we can get tailwind styles. Copy the following html codes to the app.component.html
file (taken from free samples component of tailwindui):
Run your angular app using ng serve
command and you should see something like this in the browser:
Congratulations! You just successfully integrated Tailwindcss v2.0 to an Angular 11 app!
Bundle size concerns
If you notice, when you run the app using ng serve
, the terminal shows an output like this:
Wait a minute… since we import tailwind in the styles.scss
, does it mean that tailwind really took those 11.21 MB
?! On a second thought, it’s probably because we have not built the app using the production mode, right? Let’s build the app using the command ng build --prod
. You should see the following output:
Much better, but isn’t 3.53 MB
still quite big though? Well, tailwind is actually a pretty big library to begin with. The following is the development build size from the official documentation of tailwind:
Even after being compressed with Gzip, its bundle size is considerably big; around 294.0kB
. You see, the development build is large by design. Tailwind provides thousands of utility classes for us, which we probably only use some of them. Therefore, does it not make sense that it has a big build size? However, don't fret! The author of tailwind notices this and provides a solution that can make our production build to be much much smaller than that!
Optimising tailwind for production
Now, the trick to optimise the tailwind build size is to use a 3rd party library called PurgeCSS, which is already included and used in tailwind under the hood. As the name says, it will purge all of the unused CSS when we build our app for the production. Because PurgeCSS has already been included in tailwind, we don’t need to install an additional library. Instead, we just need to add the following additional configuration in tailwind.config.js
:
The configuration presented above purges unused CSS classes in all HTML and TS files. If you’d like to know more about optimisation best practices specifically for tailwind, it is recommended to read this article from the official tailwind documentation.
There is another step though. Since tailwind purges the unused CSS by checking if NODE_ENV
is set to production
, we need to include an additional script command to our package.json
, like so:
With this, we are now ready to build our app! Let’s run npm run build:prod
command and you should see the following output:
Would you look at that! We went from a chunky 3.53 MB
to as small as 6.86 kB
with only 2 new lines added! If you are still not convinced, we can check the built files from /dist/angular11-tailwindcss/styles.{{hash}}.css
file:
As can be seen, you may not be able to find any unused tailwind utility classes as the one are being included there are only the used tailwind classes, which in our case are the CSS classes used in app.component.html
file. As a result, you should now have a production-ready application with a really small bundle size!
**Bonus: vscode css linting**
Tailwind provides several custom functions and directives that can help us produce compact yet optimised CSS codes. One that I personally used is the @apply
directive that let us instead of using tailwind utility classes directly in the template like this:
We can extract and embed tailwind utility classes to custom CSS classes like so:
This can be very handy if we still prefer the “conventional” way of writing CSS. However, if we try to use these directives specifically in VSCode, we will get something like the following:
We may get some error messages like semi-colon expected scss(css-semicolonexpected)
or Unknown at rule @responsive scss(unknownAtRules)
when trying to use a directive as the wrapper. This does not result in a compilation or build error though as this is only a linting error. As such, the above CSS codes would still work just fine. However, wouldn't it be better if we can get rid of this annoying false positive error message? Rest assured, after scrolling through the Internet, there is a possible solution.
Disable vscode css validations and extend stylelint rules
To remove the vscode css linting errors, we first need to create a user-level VSCode setting file called .vscode/settings.json
in the root folder and paste the following configs:
Then, install stylelint vscode extension:
After that, we need to install stylelint-config-standard
package as devDependencies
:
npm i -D stylelint-config-standard
Next, create a new config file called stylelint.config.js
in the root folder, with the following configurations:
Notice that we’re extending
stylelint-config-recommended
instead ofstylelint-config-standard
. The packagestylelint-config-recommended
gets automatically installed when we installstylelint-config-standard
package (check thepackage-lock.json
file).
The above configuration extends the stylelint-config-recommended
linting rules and ignores some rules that might cause unintended error messages while using tailwind’s custom functions and directives. Finally, restart your VSCode and voila, we should no longer see the linting errors:
Conclusions
To summarise, integrating Tailwindcss 2.0 with Angular 11 may look a bit daunting at first. However, with the help of some 3rd party libraries like ngx-build-plus
and figuring it out which versions of libraries we need to install, it makes the process much smoother. In addition, the built-in purge feature from Tailwind (with the help of PurgeCSS library) provides an easy way to remove unused CSS classes in the project, in which when we combine with Angular 11 production build can result in a considerably small app size!
GitHub repository
If you’d like to see the full implementation of this article, feel free to clone or view the GitHub repository here:
References
- Ngx-build-plus repository: https://github.com/manfredsteyer/ngx-build-plus
- Angular 10 with Tailwind CSS by notiz.dev: https://notiz.dev/blog/angular-10-with-tailwindcss
- Tailwindcss official documentation: https://tailwindcss.com/docs/installation
- Fix VSCode CSS linting errors: https://stackoverflow.com/questions/62118325/how-do-you-get-rid-of-these-sass-linting-errors-when-using-tailwind-css
- Adam Wathan’s blog post: https://adamwathan.me/css-utility-classes-and-separation-of-concerns/