<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dylan v.d Merwe</title>
    <description>The latest articles on DEV Community by Dylan v.d Merwe (@dylanvdmerwe).</description>
    <link>https://dev.to/dylanvdmerwe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F219354%2F05df380f-a81d-4890-8d6f-f119d2e7e500.jpg</url>
      <title>DEV Community: Dylan v.d Merwe</title>
      <link>https://dev.to/dylanvdmerwe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dylanvdmerwe"/>
    <language>en</language>
    <item>
      <title>Reduce Angular style size (using PurgeCSS to remove unused styles)</title>
      <dc:creator>Dylan v.d Merwe</dc:creator>
      <pubDate>Wed, 20 Jan 2021 21:23:13 +0000</pubDate>
      <link>https://dev.to/dylanvdmerwe/reduce-angular-style-size-using-purgecss-to-remove-unused-styles-3b2k</link>
      <guid>https://dev.to/dylanvdmerwe/reduce-angular-style-size-using-purgecss-to-remove-unused-styles-3b2k</guid>
      <description>&lt;p&gt;We want to keep our bundle sizes as low as possible right? I have been investigating how to do this, specifically around the CSS files output by Angular projects. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wait, doesn't Angular do this already?&lt;/strong&gt; Not really. Angular will put styles from your components directly into the .js files, and all third-party, library or global styles go into a dedicated styles.css in the &lt;code&gt;/dist&lt;/code&gt; folder. It won't remove any unused styles automatically. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgu4bcs772hl1g9r8ooy7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgu4bcs772hl1g9r8ooy7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to investigate some other options, and then show you the solution I ended up implementing on some of our bigger projects to show you the savings. &lt;/p&gt;

&lt;h1&gt;
  
  
  What options are there?
&lt;/h1&gt;

&lt;h3&gt;
  
  
  VSCode plugin
&lt;/h3&gt;

&lt;p&gt;We can use some plugins in our IDE to help identify styles that are not used. &lt;/p&gt;

&lt;p&gt;For example there is &lt;a href="https://marketplace.visualstudio.com/items?itemName=rcore.rcore-unused-css-classes" rel="noopener noreferrer"&gt;Unused CSS Clases for JavaScript/Angular/React&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd5iytgrt4vstiapv2z78.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd5iytgrt4vstiapv2z78.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although very useful while building pages and components it does have some drawbacks with Angular and SASS such as not correctly working with SASS mixins, understanding class bindings &lt;code&gt;[class.highlighted]="highlight"&lt;/code&gt;, or working out what is going on inside of &lt;code&gt;::ng-deep&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I do recommend doing development with this plugin installed so that you can easily pick up in your style sheets potential unused style classes that you can clean up as you go.&lt;/p&gt;

&lt;h3&gt;
  
  
  ngx-unused-css
&lt;/h3&gt;

&lt;p&gt;There is an npm package called &lt;a href="https://github.com/ivanblazevic/ngx-unused-css" rel="noopener noreferrer"&gt;ngx-unused-css&lt;/a&gt; that, when installed and run on your project, will scan your files and provide a list of all styles it deems are not used.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fykmv0xf130mv49w0ep9h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fykmv0xf130mv49w0ep9h.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I found this hard to work through in a bigger project, hence why I logged a potential &lt;a href="https://github.com/ivanblazevic/ngx-unused-css/issues/17" rel="noopener noreferrer"&gt;feature request&lt;/a&gt; to help. Probably more useful for smaller projects that do not have many components/pages. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which brings us to the solution I ended up implementing...&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  PurgeCSS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://purgecss.com/" rel="noopener noreferrer"&gt;PurceCSS&lt;/a&gt; is a well-known tool that scans the output of the built CSS files and will use it's heuristics and extractors to remove unused CSS - predominantly brought to fame thanks to &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When working in big projects, often with multiple team members or contributors, it is hard to keep track over time when styles are no longer in use. This bloats the CSS that is shipped to the browser which, while not as dramatic as large JavaScript files, does contribute towards higher data use and CPU time to parse. &lt;/p&gt;

&lt;p&gt;Getting PurgeCSS to work alongside Angular and the Angular CLI is quite a challenge for various reasons. I investigated numerous ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/58112925/how-to-integrate-purgecss-with-angular-cli-project" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/58112925/how-to-integrate-purgecss-with-angular-cli-project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@joao.a.edmundo/angular-cli-tailwindcss-purgecss-2853ef422c02" rel="noopener noreferrer"&gt;https://medium.com/@joao.a.edmundo/angular-cli-tailwindcss-purgecss-2853ef422c02&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/FullHuman/purgecss/issues/96" rel="noopener noreferrer"&gt;https://github.com/FullHuman/purgecss/issues/96&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If these work for you that is awesome. But I needed something that would fit into my project workflow and not be as intrusive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So I wrote my own npm postbuild script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In my &lt;code&gt;package.json&lt;/code&gt;, I have the following scripts:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"test-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ng"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng serve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tslint src/**/*.ts --config tslint.json --project tsconfig.json "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint:fix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tslint src/**/*.ts --config tslint.json --fix --project tsconfig.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prebuild"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node environments/prebuild.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"postbuild"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node environments/postbuild.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"update-angular"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng update @angular/cli @angular/core --allow-dirty"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can learn about npm scripts &lt;a href="https://docs.npmjs.com/cli/v6/using-npm/scripts" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Note the &lt;code&gt;postbuild&lt;/code&gt; script - npm  will run this script once the &lt;code&gt;build&lt;/code&gt; step is complete. The &lt;code&gt;build&lt;/code&gt; step just runs &lt;code&gt;ng build&lt;/code&gt; as defined above. The &lt;code&gt;postbuild&lt;/code&gt; script does &lt;em&gt;not&lt;/em&gt; run while we are doing development with &lt;code&gt;ng serve&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What I want the &lt;code&gt;postbuild&lt;/code&gt; script to do is to perform the PurgeCSS step, replace any style files that it has changed and then provide an output of any file size differences. &lt;/p&gt;

&lt;p&gt;In my environment, our tooling runs &lt;code&gt;npm run build&lt;/code&gt; and &lt;code&gt;npm run build -- --prod&lt;/code&gt; when deploying to the dev or production environments respectively. Now with the &lt;code&gt;postbuild&lt;/code&gt; script included, the PurgeCSS step will happen right after the build completes and before the deployment of any files. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The postbuild.js script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that this has been tested on Windows.&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// find the styles css file&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFilesFromPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cannot find style files to purge&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// get original file size&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFilesizeInKiloBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dist/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;originalSize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;originalSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;newSize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Run PurgeCSS...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;purgecss -css dist/*.css --content dist/index.html dist/*.js -o dist/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PurgeCSS done&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// get new file size&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFilesizeInKiloBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dist/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;newSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getFilesizeInKiloBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;statSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fileSizeInBytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fileSizeInBytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getFilesFromPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readdirSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Make sure to run &lt;code&gt;npm i -D purgecss&lt;/code&gt; to install the right dependency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's see some examples
&lt;/h2&gt;

&lt;p&gt;All of these projects are using &lt;strong&gt;Angular 11&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Medium-size project
&lt;/h4&gt;

&lt;p&gt;This is the output of a medium sized project that includes Bootstrap and has multiple style sheets for different clients. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Run PurgeCSS...
PurgeCSS done

┌─────────┬───────────────────────────────────┬──────────────┬───────────┐
│ (index) │               file                │ originalSize │  newSize  │
├─────────┼───────────────────────────────────┼──────────────┼───────────┤
│    0    │       'benefitexchange.css'       │  '148.48kb'  │ '36.89kb' │
│    1    │       'creativecounsel.css'       │  '148.46kb'  │ '36.89kb' │
│    2    │        'fibrecompare.css'         │  '148.35kb'  │ '36.77kb' │
│    3    │          'filledgap.css'          │  '148.07kb'  │ '36.68kb' │
│    4    │            'hippo.css'            │  '148.43kb'  │ '36.86kb' │
│    5    │          'klicknet.css'           │  '148.49kb'  │ '36.89kb' │
│    6    │            'mondo.css'            │  '148.44kb'  │ '36.87kb' │
│    7    │           'nedbank.css'           │  '148.63kb'  │ '37.05kb' │
│    8    │         'phonefinder.css'         │  '148.41kb'  │ '36.85kb' │
│    9    │       'realpromotions.css'        │  '148.46kb'  │ '36.88kb' │
│   10    │ 'styles.428c935b7c11a505124a.css' │  '33.96kb'   │ '20.33kb' │
└─────────┴───────────────────────────────────┴──────────────┴───────────┘


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;There are some dramatic savings where huge chunks of unused Bootstrap and other library styles are removed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Large enterprise project
&lt;/h4&gt;

&lt;p&gt;This is the output of a large enterprise project that makes use of &lt;a href="https://dev.toNG-ZORRO"&gt;https://github.com/NG-ZORRO/ng-zorro-antd&lt;/a&gt;. There are plenty of other dependencies such as &lt;code&gt;ngx-dropzone&lt;/code&gt;, &lt;code&gt;lightgallery.js&lt;/code&gt;, &lt;code&gt;ngx-toastr&lt;/code&gt;, &lt;code&gt;web-social-share&lt;/code&gt;, etc. &lt;/p&gt;

&lt;p&gt;There were some issues with some components in NG-ZORRO such as the date picker and the steps component not working at run time. These will need to be raised with the project maintainers to hopefully resolve - otherwise you may need to use other libraries. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Run PurgeCSS...
PurgeCSS done

┌─────────┬───────────────────────────────────┬──────────────┬────────────┐
│ (index) │               file                │ originalSize │  newSize   │
├─────────┼───────────────────────────────────┼──────────────┼────────────┤
│    0    │ 'styles.72918fcbd85fee3bb2a8.css' │  '545.01kb'  │ '231.97kb' │
└─────────┴───────────────────────────────────┴──────────────┴────────────┘


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Again, a huge reduction thanks to unused styles being removed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some caveats
&lt;/h2&gt;

&lt;p&gt;Make sure you &lt;strong&gt;test your code&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In my experience, the less complicated the project the better this approach will work. Once you start using more complicated UI tools and packages (such as NG-ZORRO or Angular Material) you may run into situations where PurgeCSS is not able to determine styles that are used due to run-time interactions on components and these styles will be stripped, causing some very weird looking sites. &lt;/p&gt;

&lt;p&gt;Also note that solution will &lt;strong&gt;only&lt;/strong&gt; work on CSS files, it will not remove any styles that Angular builds into your .js files from your components. &lt;em&gt;Now that would take this to the next level&lt;/em&gt; - but I think think would require more integration with Webpack and the Angular CLI.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I was struggling to manually identify and remove unused styles in my company's Angular projects in order to 1) keep bloat down and 2) ensure the site is as lean as possible. &lt;/p&gt;

&lt;p&gt;By implementing a &lt;code&gt;postbuild&lt;/code&gt; npm script that runs PurgeCSS on the build output, we have seen some dramatic reductions in style size. I do recommend cleaning up your own CSS or SASS files as the primary measure. &lt;/p&gt;

&lt;p&gt;Overall the majority of projects worked without any changes, but your mileage may vary.&lt;/p&gt;

&lt;p&gt;I would love to know if this solution works for you, what size reductions you are getting or if you have any other thoughts on this. &lt;/p&gt;

</description>
      <category>angular</category>
      <category>css</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
