Solution to no CSS source map file generated under production mode in Webpack 4

The issue is in Webpack 4 under "production" mode there is no source map file generated only for CSS (no problem in javascript source map file) but there is no issue in generation of source map for CSS under "development" mode.

Here are my previous configurations:

package.json

  
{
  "name": "webfoobar",
  "version": "1.0.0",
  "author": "Roland Michael dela Peña",
  "homepage": "http://localhost",
  "description": "",
  "main": "",
  "keywords": [],
  "license": "ISC",
  "scripts": {
    "prod": "webpack --mode production",
    "dev": "webpack --watch  --mode development"
  },
  "devDependencies": {
    "autoprefixer": "^9.1.0",
    "css-loader": "^1.0.0",
    "cssnano": "^4.0.5",
    "mini-css-extract-plugin": "^0.4.1",
    "node-sass": "^4.9.2",
    "optimize-css-assets-webpack-plugin": "^5.0.0",
    "postcss-loader": "^2.1.6",
    "sass-loader": "^7.1.0",
    "webpack": "^4.16.3",
    "webpack-command": "^0.4.1"
  }
}
  

webpack.config.js

  
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = (env = {}, argv = {}) => {
  const isDevelopment = (env.mode === 'development');
  const isProduction = (env.mode === 'production');

  return {
    entry: {
      app: [
        './src/main.scss'
      ]
    },
    output: {
      path: path.resolve(__dirname, './dist'),
      filename: 'scripts.js',
      sourceMapFilename: '[file].map'
    },
    devtool: 'source-map',
    module: {
      rules: [
        {
          test: /\.(css|s[ac]ss)$/,
          use: [
            {
              loader: MiniCssExtractPlugin.loader
            },
            {
              loader: 'css-loader',
              options: {
                importLoaders: 2,
                sourceMap: true
              }
            },      
            {
              loader: 'postcss-loader',
              options: {
                plugins: () => [
                  require('autoprefixer')
                ],
                sourceMap: true
              }
            },
            {
              loader: 'sass-loader',
              options: {
                sourceMap: true
              }
            }
          ]
        }
      ],
    },
    optimization: {
      minimizer: [
        new OptimizeCSSAssetsPlugin({})
      ]
    },
    plugins: [
      new MiniCssExtractPlugin({
        filename: '[name].css',
        chunkFilename: '[id].css'
      })
    ]
  }
};
  

The webpack output after building the "production" mode:

CSS sourcemap generation failed Webpack output

We can see that there is no "app.css.map" generated.

After some trial and error, I have found the culprit which is the "Optimize CSS Assets Webpack Plugin". I use this plugin to minimize the CSS file size which by default it uses "cssnano". Analyzing the "webpack.config.js" we can use the "PostCSS loader" to this job by using "cssnano" also.

Here are my new configurations:

package.json

  
{
  "name": "webfoobar",
  "version": "1.0.0",
  "author": "Roland Michael dela Peña",
  "homepage": "http://localhost",
  "description": "",
  "main": "",
  "keywords": [],
  "license": "ISC",
  "scripts": {
    "prod": "webpack --mode production",
    "dev": "webpack --watch  --mode development"
  },
  "devDependencies": {
    "autoprefixer": "^9.1.0",
    "css-loader": "^1.0.0",
    "cssnano": "^4.0.5",
    "mini-css-extract-plugin": "^0.4.1",
    "node-sass": "^4.9.2",
    "postcss-loader": "^2.1.6",
    "sass-loader": "^7.1.0",
    "webpack": "^4.16.3",
    "webpack-command": "^0.4.1"
  }
}
  

webpack.config.js

  
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = (env = {}, argv = {}) => {
  const isDevelopment = (env.mode === 'development');
  const isProduction = (env.mode === 'production');

  return {
    entry: {
      app: [
        './src/main.scss'
      ]
    },
    output: {
      path: path.resolve(__dirname, './dist'),
      filename: 'scripts.js',
      sourceMapFilename: '[file].map'
    },
    devtool: 'source-map',
    module: {
      rules: [
        {
          test: /\.(css|s[ac]ss)$/,
          use: [
            {
              loader: MiniCssExtractPlugin.loader
            },
            {
              loader: 'css-loader',
              options: {
                importLoaders: 2,
                sourceMap: true
              }
            },      
            {
              loader: 'postcss-loader',
              options: {
                plugins: () => [
                  require('autoprefixer'),
                  require('cssnano')({
                      preset: 'default',
                  })
                ],
                sourceMap: true
              }
            },
            {
              loader: 'sass-loader',
              options: {
                sourceMap: true
              }
            }
          ]
        }
      ],
    },
    plugins: [
      new MiniCssExtractPlugin({
        filename: '[name].css',
        chunkFilename: '[id].css'
      })
    ]
  }
};
  

The webpack output after building the "production" mode:

CSS sourcemap generation successful Webpack output

Now the "app.css.map" is generated under "production" mode.

Comments

Thank you for sharing, helped a lot! Chris

I have been spending half the day trying to make sense of enabling sourcemaps through webpack 4 based on various blogs. This is the only source on the web that comes close to making that happen perfectly. I had to make some tweaks based on the info above, but overrall this is a beauty for Webpack users. Many thanks!

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.