In development mode, Tailwind might be several hundred Kb large, if not into the megabytes depending on which classes you use. That's definitely not something we want to ship to our production environment. Therefore, Tailwind comes with CSS purging, a build step that analyzes your HTML, components, etc and removes all the unused Tailwind CSS from the overall bundle, shrinking down the Tailwind CSS to the bare minimum.
Normally you would just set this up for the app you're installing Tailwind for, but in a Nx workspace, you might have multiple apps and multiple libraries (shared or not). Hence, we don't just want to purge app-specific HTML files, but also those of the libs we use. Nx comes with built-in support to automatically generate glob patterns based on the libraries consumed by a given application.
Prefer to read along as well? Here's the accompanying article.
Juri Strumpflohner: [0:00] What makes working with Tailwind really nice is that by importing in our global styles.css file, these three things, we are set up to style our page for whatever we need. Basically, we can just apply here these specific classes on top of our DOM elements, and then they will get styled.
[0:20] What does that mean in terms of the bundle size, ultimately, because we used Next.js specifically, to make sure that we have a good Lighthouse score in the end, so a small bundle that loads up fast? Let's have a look.
[0:33] We can use the nx build command, and pass in the name of our project -- which is, in this case, site -- to create a build of our artifact. If we scroll up here, we see the CSS that gets created. That's huge. We just have one index.tsx file with a couple of classes on top of that, and it is 306 kilobytes. This can get even worse, up into the megabytes, if you add things such as typography, dark mode, and things like that.
[1:03] If you go over to the Tailwind docs, there's a specific section for "Optimizing for Production" where in fact they specify that the development build of Tailwind can get up to multiple megabytes uncompressed. We definitely want to make sure that we tear that down to whatever we are just using on our website.
[1:20] Tailwind has that method that is called Purging. That means it would scan your CSS files, your HTML files, your components for unused Tailwind classes and remove them from the overall CSS. You can do that by configuring that purge option and giving it all the globs to potential sources where Tailwind is being used, in our HTML files, even if you use Vue.js, in your Vue files, JSX, or TSX files.
[1:48] If you go back to our application setup, let's find our Tailwind config. Let's have a look what we have in there. Right now, you can see our purge option here is empty. The one thing we definitely want to do is we want to purge everything that is within that pages folder because that's where our components live right now.
[2:07] Again, we can use the join functionality to directly generate that path to those files. We can import that from the path node utility. Then, we go down here. We join basically with the current directory name. Then, we would pass in something like 'pages/**/*.{js, ts, jsx, tsx}' files.
[2:32] Futhermore, the Tailwind docs mention that whenever you compile your CSS, make sure that the 'NODE_ENV' is set to 'production' so Tailwind will automatically purge unused styles from your CSS. That's already taken care of by Nx, so we could just check that out and retry our build now.
[2:50] Once that builds finishes, you can see now that the CSS file is much smaller. It's actually just 1.8 kilobytes compared to the more than 300 kilobytes which we had before. The purging actively works.
[3:02] There's more we might want to do, though, since we live in monitoring per scenario within Nx. In Nx application, you don't just have the things within that pages folder, so structured within that apps folder. Rather what you do is usually split up the logic into different libraries, which are then consumed by some application or by even multiple applications up here in that apps folder.
[3:23] That means the apps folder in theory is really thin. It just combines things out of that libs folder. We could actually create a glob that includes all the libs folders. In our small example, this would actually work perfectly. However, as you scale and as you have a more real-world scenario, that might be a waste of computation power.
[3:42] What we did in Nx is actually create some utilities that allow you to dynamically collect those library glob patterns based on whatever you use within your application. Let's have a look.
[3:52] We can import that from the utility provided from nrwl/next/tailwind, and that exposes a function that is called createGlobPatternsForDependencies. What we can do is we can go up to that purge array here and destructure it by invoking a function directly with the current directory name.
[4:15] You have, then, more options in the sense of providing some custom file glob patterns. Basically, if you don't want to include all the js, ts, jsx, tsx files, you can also provide a custom one that will be attached to the generated glob patterns.
[4:30] Overall, what this function does, it automatically uses the internal Nx dependency graph to understand whatever you import here in that site project from that libs folder down here would also be included in the overall purge patterns here.
[4:44] As a result, you would only really purge whatever you're using. Thus, it would be efficient during the build time but also make sure you actually include everything that should be included.
[4:53] Since we don't have any libs yet, the actual build would be the same. It will still be very small. You can see it's still 1.8 kilobytes. Nothing actually changed. As we evolve in this course and create more content down in that libs folder, we would actually start benefiting from this utility function.