Here I'm going to post whatever that is interesting for me. All things about programming using JavaScript and ASP.NET Core. And something else.

A blog about ASP.Net Core and JavaScript

A few days ago I realized that stylesheet on one of my sites wasn't minified. The quick investigation showed that minify option of the webpack css-loader didn’t work anymore. I researched this problem and found that since version 1.0.0 the css-loader doesn't contain the minimize option (see changelog).

In this post, I will show how to keep your CSS minimized by using the PostCSS loader with cssnano.

I will use the Asp.Net Core project, configured as showed in one of my previous posts “Using webpack 4 with ASP.NET Core 2.x MVC application to process ES6 scripts and SASS styles” and will modify it in a proper way.

So, let’s do it.

Contents

Downloading a sample project

You can find the source code of a sample project from my previous post “Using webpack 4 with ASP.NET Core 2.x MVC application to process ES6 scripts and SASS styles” at AspNetWebpack repository on GitHub.

Removing old npm packages

At this step, we will remove all developing dependencies. We don’t need some of them, and we will update the necessary packages to latest versions.

Using the command prompt, move to the project directory (I have it inside D:\Projects\DotNetCore\AspNetWebpack directory)

cd /d D:\Projects\DotNetCore\AspNetWebpack\AspNetWebpack

and run the next command:

npm uninstall --save-dev webpack webpack-cli css-loader extract-loader file-loader node-sass sass-loader style-loader

This uninstalls all packages listed in the command arguments

Uninstalling old NPM packages

and removes their names from package.json.

{
  "name": "aspnetwebpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --progress --profile",
    "watch": "webpack --progress --profile --watch",
    "production": "webpack --progress --profile --mode production"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
  },
  "dependencies": {
    "lodash": "^4.17.11"
  }
}

 

Installing new packages

To install necessary NPM packages, run the next:

npm install --save-dev webpack webpack-cli style-loader sass-loader postcss-loader node-sass mini-css-extract-plugin cssnano css-loader clean-webpack-plugin

 

Installing new packages

After this step, the package.json has to look like this.

{
  "name": "aspnetwebpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --progress --profile",
    "watch": "webpack --progress --profile --watch",
    "production": "webpack --progress --profile --mode production"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^0.1.19",
    "css-loader": "^1.0.1",
    "cssnano": "^4.1.7",
    "mini-css-extract-plugin": "^0.4.4",
    "node-sass": "^4.10.0",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2"
  },
  "dependencies": {
    "lodash": "^4.17.10"
  }
}

Configuring PostCSS

To configure PostCSS to minify final stylesheets, add the postcss.config.js file to the ..\AspNetWebpack\src\sass\ folder.

Add the next source code to the postcss.config.js:

module.exports = ({ options }) => {
    const plugins = [];
    if (options.env === 'production') plugins.push(require('cssnano'));
    return {
        plugins: plugins
    };
};

Here, we add the cssnano plugin to the plugins array only when the env option is equal to “production”.

Don’t forget to save the postcss.config.js file.

Reconfiguring webpack

Change the webpack.config.js as below:

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');

const bundleFileName = 'bundle';
const dirName = 'wwwroot/dist';

module.exports = (env, argv) => {
    return {
        mode: argv.mode === "production" ? "production" : "development",
        entry: ['./src/index.js', './src/sass/index.scss'],
        output: {
            filename: bundleFileName + '.js',
            path: path.resolve(__dirname, dirName)
        },
        module: {
            rules: [
                {
                    test: /\.s[c|a]ss$/,
                    use:
                        [
                            'style-loader',
                            MiniCssExtractPlugin.loader,
                            'css-loader',
                            {
                                loader: 'postcss-loader',
                                options: {
                                    config: {
                                        ctx: {
                                            env: argv.mode
                                        }
                                    }
                                }
                            },
                            'sass-loader'
                        ]
                }
            ]
        },
        plugins: [
            new CleanWebpackPlugin(dirName, {}),
            new MiniCssExtractPlugin({
                filename: bundleFileName + '.css'
            })
        ]
    };
};

 

Here we use arrow function to get webpack-cli arguments. This function returns webpack configuration object. We need the --mode argument from webpack-cli (see “scripts” property inside the package.json file). This value is packed to the argv.mode parameter and is used in mode property to affect on final JavaScript code minification. Also, we use it to configure PostCSS loader via the options.config.ctx.env property. Additionallythe destination directory will be cleaned with the CleanWebpackPlugin.

Note, that PostCSS loader configuration object MUST BE BEFORE  the sass-loader!

After saving all changes, you can develop your product as usually (see "Using webpack 4 with ASP.NET Core 2.x MVC application to process ES6 scripts and SASS styles"). But this time, when you’re in “production”  mode, the resulting JavaScript and CSS files will be minified.

You can find the whole source code at AspNet21Webpack4 repository on GitHub.

That’s all and happy codding!