11

I'm trying to use purgecss to remove any unused css, particularly the unused css from Bootstrap. With Purgecss setup, all my css is being removed, and only inline styling remains. This means purgecss is removing the styling for all css classes, not just the ones that aren't being used. I would like to get my configuration correct, so that only the css styles which are not being used are removed.

Since my React App also uses Post-css, I'm trying to to use the postcss-purgecss plugin, and have followed the instructions at that link for setup.

This is happening in development and production mode.

You can test out the problem on this branch of this github repo

You can view the result of whats happening at this url https://purge-css-failing.netlify.app/


postcss.config.js

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

module.exports = {
  plugins: [
    purgecss({
        content: ['./src/**/*.html']
    }),
  ]
};

webpack.config.js

const path = require('path');
var webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { GenerateSW } = require("workbox-webpack-plugin");
const WebpackPwaManifest = require("webpack-pwa-manifest");

'use strict';
module.exports = {
  target: "web",
  mode: "development",
  entry: "./src/entryPoints/index.jsx",
  devtool: "source-map",
  output: {
    path: path.resolve(__dirname, "dist"),
    publicPath: "/",
    filename: "[name]/[name].js",
  },
  module: {
    rules: {
      test: /\.(scss|css)$/,
      use: [
        MiniCssExtractPlugin.loader, // creates style nodes from JS strings
        {
          loader: "css-loader", // translates CSS into CommonJS
          options: {
            importLoaders: 1,
          },
        },
        "postcss-loader", // post process the compiled CSS
        "sass-loader", // compiles Sass to CSS, using Node Sass by default
      ],
    }
  },
  devServer: {...},
  resolve: {...},
  plugins: [
    new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV: JSON.stringify("development"),
      },
    }),
    new HtmlWebpackPlugin({
      template: "./html/index.html",
      filename: "./index.html",
    }),
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[name].css",
    }),
    new WebpackPwaManifest({
      icons: [
        {
          src: path.resolve(
            "src/assets/images/Favicon/android-chrome-192x192Circle.png"
          ),
          sizes: "192x192",
          type: "image/png",
          purpose: "any maskable",
        },
        {
          src: path.resolve("src/assets/images/logo/icon.png"),
          sizes: "512x512",
          type: "image/png",
        },
      ],
      name: "Example",
      short_name: "Example",
      orientation: "portrait",
      start_url: "/",
      theme_color: "#000000",
      background_color: "#ffffff",
      description: "Description",
      display: "standalone", //property set to fullscreen, standalone, or minimal-ui
      prefer_related_applications: false, //Says if you would prefer that the user download a mobile app from the app store or something
    }),
    new GenerateSW({
      // option: 'value',
    }),
  ],
};
Sam
  • 1,765
  • 11
  • 82
  • 176
  • "This is happening in development mode", does that mean it doesn't happen in production mode? – Barthy May 17 '21 at 14:10
  • @Barthy It is also happening in production mode – Sam Aug 05 '21 at 01:25
  • Hello again. The solution I came up with the same as Oluwafemi's answer. It works fine. Try it again, but don't forget to restart the `npm start` dev-server after every change in config files. Also, I suggest keeping both html and js extensions in the `content` array. – Barthy Aug 05 '21 at 08:49

1 Answers1

9

Since your app is a ReactJS App, you want to purge css classes not used in the Javascript bundle compiled for the dev or production environment.

You can update your postcss.config.js file to match on .js files.

module.exports = {
  plugins: [
    purgecss({
      content: ["./src/**/*.js"],
      // Treat every word in the bundle as a CSS selector
      defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || []

    }),
  ]
};
Oluwafemi Sule
  • 36,144
  • 1
  • 56
  • 81
  • I have the exact ssame prblem that I was having before with this – Sam May 25 '21 at 19:30
  • Nothing jumps out in the configuration you have provided. Are your assets bundled in a part other than `./src` when in development mode? – Oluwafemi Sule May 25 '21 at 20:04
  • Yeah, they all get minified into a `./main.css` file, I have lots of folders with an `index.js` and a `style.scss` and the `index.js` has a line that looks like `import './style.scss'`. The MiniCssExtractPlugin is the thing that's bundling all the css into the main.css. I think I might have to call purgecss before I call the MiniCssExtractPlugin – Sam Jun 04 '21 at 20:46
  • You can view the repo at https://github.com/samgermain/react-boiler-plate/tree/purgecss and view the result at https://purge-css-failing.netlify.app/ – Sam Aug 05 '21 at 01:34
  • A `main.css` is output when I build the respository that you shared. Could you share a branch where this issue is reproducible in? – Oluwafemi Sule Aug 05 '21 at 17:17