17

I have an Angular project created with Angular CLI, so I have angular.json file for configuring the build.

I wanted to integrate PurgeCSS as it seems to be a great tool to reduce the size of our CSS bundle.

On PurgeCSS website, they explain how to integrate with Webpack. I found a tutorial that explains how to add custom webpack integration with Angular CLI.

Did anyone have a successful example of PurgeCSS integrated with Angular CLI project ?

Tonio
  • 4,082
  • 4
  • 35
  • 60

4 Answers4

31

There is another way which is more in line with Angular CLI and Webpack config:

You need to install

npm install -D @angular-builders/custom-webpack postcss-scss @fullhuman/postcss-purgecss

Then create a webpack.config.js config file:

const purgecss = require('@fullhuman/postcss-purgecss')

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        loader: 'postcss-loader',
        options: {
          ident: 'postcss',
          syntax: 'postcss-scss',
          plugins: () => [
            require('postcss-import'),
            require('autoprefixer'),
            purgecss({
              content: ['./**/*.html'],
              // Example to let PurgeCss know how to exclude cdk and mat prefixes if your using Angular CDK and Angular Material
              whitelistPatterns: [/^cdk-|mat-/]
            })
          ]
        }
      }
    ]
  }
};

Then change your angular.json file to use this new configurations:

...
"build": {
  "builder": "@angular-builders/custom-webpack:browser",
  "options": {
    "customWebpackConfig": {
      "path": "webpack.config.js"
    },
    ...
  }
},
...

Make sure you run this configuration only in production mode, when you bundle the final application.

Hope this helps.

I created a post to explain how in detail - https://medium.com/@joao.a.edmundo/angular-cli-tailwindcss-purgecss-2853ef422c02

Francesco Borzi
  • 56,083
  • 47
  • 179
  • 252
Joao Edmundo
  • 429
  • 1
  • 4
  • 7
  • 3
    How do I do this if I already have a `"builder": "@angular-devkit/build-angular:browser",`? This is used for the `ng build --prod` command. Can I use multiple builders somehow? – user2619824 Aug 19 '20 at 22:00
  • 1
    For me it seems to not work when I have some import inside my style.scss. E.g. @import 'custom-variables'; https://stackoverflow.com/questions/60210139/post-css-not-finding-paths-from-node-modules – Stefan Aug 25 '20 at 10:14
  • @user2619824 "@angular-builders/custom-webpack:browser" is a replacement for the default builder. – wheredidthatnamecomefrom Feb 24 '22 at 19:27
21

I created this bash script to use PurgeCSS with my Angular app. It reduced my 'styles.css' file size from 63kb to only 3kb! Hope it works for you too.

Steps:

  1. create a new file named purgecss.sh inside your project folder
  2. insert the code below into purgecss.sh file
  3. run ./purgecss.sh from CLI
#!/bin/bash

# run production build
ng build --prod --output-hashing none

# go to the dist/yourProjectName folder
cd ./dist/yourProjectName

# make a new directory named 'css' (you can name it anything)
mkdir css

# run PurgeCSS & make a new '.css' file inside the 'css' directory
purgecss --css ./styles.css --content ./index.html ./*.js --out ./css

# replace the 'dist/yourProjectName/styles.css' file with the 'dist/yourProjectName/css/styles.css' file
mv ./css/styles.css ./styles.css

# delete the previously created 'css' directory
rm -r css
snsakib
  • 1,062
  • 9
  • 14
18

This configuration works for me and giving me results from 126kb to 34kb on my styles.[hash].css output for production build.

First, install this:

npm install -D @angular-builders/custom-webpack purgecss-webpack-plugin

Then, create webpack.config.js in the root of the project:

const glob = require('glob');
const PurgeCSSPlugin = require('purgecss-webpack-plugin');

module.exports = {
  plugins: [
    new PurgeCSSPlugin({ paths: glob.sync('./src/**/*.html', { nodir: true }) })
  ]
};

and edit your angular.json configuration as follows:

"architect": {
   "build": {
     "builder": "@angular-builders/custom-webpack:browser",
     "options": {
       "customWebpackConfig": {
         "path": "webpack.config.js"
       },
       ...

My result without this plugin:

styles.ca3c7399cc89e60cfa2d.css   | styles        | 128.99 kB

And now with the purgecss-webpack-plugin:

styles.ca3c7399cc89e60cfa2d.css   | styles        |  34.46 kB

Which is amazing, first when I saw this output I went checked my app in the browser and all styles have been included properly :-).

Only downside may be that this doesn't work on inlined html if any in angular components, I think.

Florian Gössele
  • 4,376
  • 7
  • 25
  • 49
Jan Kuri
  • 927
  • 12
  • 17
  • 3
    Thanks for the great solution. I want to add an addition: glob.sync('./src/**/*.html' selecting HTML files might be caused bugs. Because you can set a class name in TS files. Selecting all files ('./src/**/*') is a good choice. – Mehmet Erim Mar 20 '21 at 21:12
  • Note: since Webpackage 5: `const { PurgeCSSPlugin } = require('purgecss-webpack-plugin'); ` – luke8800gts Feb 22 '23 at 12:06
  • Also with the modification of @MehmetErim, it still removes to much (for simple projects this might work, for advanced one you probably will encounter some strange styling problems) – luke8800gts May 05 '23 at 08:41
2

You can simply run the following commands in your project root directory

npm i -D postcss-import postcss-loader postcss-scss
ng add ngx-build-plus

In angular.json, make the following replacements in "architect" section:

"builder": "@angular-devkit/build-angular:browser" with "builder": "ngx-build-plus:browser" under "build",

"builder": "@angular-devkit/build-angular:dev-server" with "builder": "ngx-build-plus:dev-server" under "serve",

"builder": "@angular-devkit/build-angular:karma" with "builder": "ngx-build-plus:karma" under "test",

You should also add "extraWebpackConfig": "webpack.config.js" under options in the respected sections.

Jabir Minjibir
  • 119
  • 1
  • 6