'Produce sourcemap from compiled SASS in webpack4

My project is not a JS web app. It is a traditional CMS with PHP templates that invoke the needed JS and CSS files. I'm using webpack4 with this goals:

  1. For JS: Bundle, minify, polyfill, and create a js sourcemap --which is working well, no problem here.
  2. Copy assests (fonts and images) from a folder in src. to another in dist. --working too.
  3. For my SCSS files: compile Sass from a given directory, add prefixes, and output a single css file onto an specific folder, including the CSS SOURCEMAP. Everything is working BUT I cannot generate the CSS sourcemap. I can do all this with Grunt, but I was hoping to only use one tool -webpack!

I'm pasting my config file to see if anyone spots what is wrong.

I already tried adding options:{ sourceMap:true,} to this loaders: sass-loader, postcss-loader, css-loader but then I get a long list of errors that seem to emanate from extrac-loader.

I appreciate any hints or help on this issue. I already spent 2 days troubleshooting it without any progress!

    const path = require('path');
    const OptimizeCSSAssetsPlugin = require(
      "optimize-css-assets-webpack-plugin"
    ); // Recommended for Minifying outputted css
    const cssnano = require("cssnano"); // Used by OptimizeCSSAssetsPlugin 
    var webpack = require('webpack'); // used by SourceMapDevToolPlugin --which was recommended over devtool.

    module.exports = {
        cache: false,
        entry: {
            'main': [ // forces webpack to process specified files
                     '../src/js/main.js',
                     '../src/sass/screen.scss',
                     ],
        },
        output: {
            filename: '[name].bundle.js',
            path: path.resolve(__dirname, '../dist/js'), // watchout: all output paths in 'rules' will be relative to this path
        },
        mode: 'development',
        devtool: false, // passes sourcemap control to SourceMapDevToolPlugin
        module:{
            rules: [
                {
                    test: /\.scss$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                name: '../css/[name].css', // Destination of final processed css file
                            }
                        },
                        {
                            loader: 'extract-loader', //The extract-loader evaluates the given source code on the fly and returns the result as string.
                        },
                        {
                            loader: 'css-loader?-url', //The css-loader interprets @import and url() like import/require() and will resolve them.

                        },
                        {
                            loader: 'postcss-loader', // adds prefixes
                        },
                        {
                            loader: 'sass-loader', // Loads a Sass/SCSS file and compiles it to CSS
                        },
                    ]
                },
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets:
                            [
                                '@babel/env',
                                {
                                    // "corejs": 3,
                                }
                            ]
                        }
                    }
                },

            ] // End of rules
        }, // End of module
        plugins: [
            new webpack.SourceMapDevToolPlugin(
                {
                    filename: '[name].map',
                    columns: false,
                     module: true,
                }
            ),
            new OptimizeCSSAssetsPlugin({
              cssProcessor: cssnano,
              cssProcessorOptions:  {
                      discardComments: {
                        removeAll: true,
                      },
                      // Run cssnano in safe mode to avoid
                      // potentially unsafe transformations.
                      safe: true,
                    },
              canPrint: false,
            }),
          ],
    } // End of module.exports


Solution 1:[1]

Ok, my approach was wrong. Modified a few things and now I have sourcemaps for js and css files.

I'm pasting my webpack.config file in case someone finds it useful (maybe this is obvious for most, but I'm new to webpack, hopefully this will help another newbie like me).

Changes I did: I turns out that extract-loader and file-loader were not needed. I used mini-css-extract-plugin instead... which allows for the sourcemaps.

There's a conflict with optimize-css-assets-webpack-plugin (if you are using it for minification), so check the plugin part configuration to make sure your sitemaps are generted.

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // extracts and saves css files
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); // Minifies css
const cssnano = require("cssnano"); // Used by OptimizeCSSAssetsPlugin  in the css minification
var webpack = require('webpack'); // used by SourceMapDevToolPlugin

module.exports = {
    cache: false,
    entry: {
        'main': [ // forces webpack to process specified files
                 '../src/js/main.js',
                 '../src/sass/main.scss',
                 ],
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, '../dist/js'), // watchout: all output paths in 'rules' will be relative to this path
    },
    mode: 'development',
    devtool: false, // passes sourcemap control to SourceMapDevToolPlugin
    module:{
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets:
                        [
                            '@babel/env',
                            {
                                // "corejs": 3,
                            }
                        ]
                    }
                }
            },
            {
                test: /\.scss$/,
                use: [
                        {
                            loader: MiniCssExtractPlugin.loader,
                            options: {
                              publicPath: '/public/path/to/',
                            },
                        },

                        {
                            loader: 'css-loader', //The css-loader interprets @import and url() like import/require() and will resolve them.
                            options: {
                                url: false,
                                sourceMap: true,
                            },
                        },

                        {
                            loader: 'postcss-loader',  // adds prefixes
                            options: {
                                sourceMap: true,
                            },
                        },

                        {
                            loader: 'sass-loader', // Loads a Sass/SCSS file and compiles it to CSS
                            options: {
                                sourceMap: true,
                                // importer: globImporter(),
                            },
                        },
                ]
            },

        ] // End of rules
    }, // End of module
    plugins: [
        new MiniCssExtractPlugin({
            filename: '../css/[name].css'
        }),
new OptimizeCSSAssetsPlugin({
          cssProcessor: cssnano,
          cssProcessorOptions:  {
                  map: {
                    inline: false,  // set to false if you want CSS source maps
                    annotation: true
                  },
                  discardComments: {
                    removeAll: true,
                  },
                  // Run cssnano in safe mode to avoid
                  // potentially unsafe transformations.
                  safe: true,
                },
          canPrint: false,
        }),
        new webpack.SourceMapDevToolPlugin(
            {
                filename: '[name].map',
                columns: false,
                 module: true,
            }
        ),
      ],
} // End of module.exports

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mauricio