Webpack source-map does not resolve sass imports

Viewed 1577

I have webpack configured to transpile scss -> css, but sourcemap generated by webpack does not resolve scss @imports.

webpack.config.js:

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const outputPath = path.join(__dirname, 'dist');

module.exports = {
    devtool: 'source-map',
    entry: ['./src/main.scss'],
    target: 'web',
    output: {
        filename: 'js/[name].bundle.js',
        path: outputPath
    },
    module: {
        rules: [
            { // sass / scss loader for webpack
                test: /\.(sass|scss)$/,
                loader: ExtractTextPlugin.extract([
                    {
                        loader: 'css-loader',
                        options: {
                            url: false,
                            import: true,
                            minimize: true,
                            sourceMap: true,
                        }
                    },
                    'sass-loader'
                ])
            },
        ]
    },
    plugins: [
        new ExtractTextPlugin({ // define where to save the file
            filename: 'css/[name].bundle.css',
            allChunks: true,
        })
    ]
};

main.scss:

@import 'foo';

_foo.scss:

h1 { color: red; }

However, in Chrome dev tools, I see a reference to main.scss where I expect reference to _foo.scss - see the screenshot below:

_foo.scss not resolved

Compiled demo: http://store.amniverse.net/webpacktest/

3 Answers

You should not use extractTextPlugin when you are in dev mode. Please make extra configs for dev and production mode. In production the use of extractTextPlugin is fine but in dev mode it is not necessary and can lead to other features not working. So instead use the style-loader.

Also - I am not sure if that fixes your problem - try to use importLoaders prop on the css loader. Look here for more info:

https://github.com/webpack-contrib/css-loader#importloaders

const path = require('path');

const outputPath = path.join(__dirname, 'dist');

module.exports = {
    devtool: 'source-map',
    entry: ['./src/main.scss'],
    target: 'web',
    output: {
        filename: 'js/[name].bundle.js',
        path: outputPath
    },
    module: {
        rules: [
            { // sass / scss loader for webpack
                test: /\.(sass|scss)$/,
                loader: [
                    {
                        loader: 'style-loader',
                        options: {
                          sourceMap: true
                        }
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            url: false,
                            import: true,
                            minimize: true,
                            sourceMap: true,
                            importLoaders: 1,
                        }
                    },
                    {
                       loader: 'sass-loader',
                       options: {
                         sourceMap: true
                       }
                    }
                ]
            },
        ]
    }
};

You have sass-loader there, switch it with:

{
   loader: 'sass-loader',
   options: {
     sourceMap: true
   }
}

And that would work.

There's nothing wrong with ExtractTextPlugin in dev mode, and what @Omri Aharon posted is correct. However, what you should consider is having source-map enabled only in dev mode.

To build webpack using its default production settings (which uglifies and applies OccurrenceOrderPlugin plugin by default in webpack 2.0+), run the command webpack -p, and then in your webpack.config.js, you can determine if you're in dev mode or not by doing:

const DEBUG = !process.argv.includes('-p');

Add the function

function cssConfig(modules) {
    return {
        sourceMap: DEBUG,
        modules,
        localIdentName: DEBUG ? '[name]_[local]_[hash:base64:3]' : '[hash:base64:4]',
        minimize: !DEBUG
    };
}

in your webpack.config.js, making your scss loader appear as so:

            test: /\.(sass|scss)$/,
            loader: ExtractTextPlugin.extract({
                fallback: 'style-loader',
                use: [
                    {
                        loader: 'css-loader',
                        options: cssConfig(true)
                    },
                    {
                        loader: 'sass-loader',
                        options: { sourceMap: DEBUG }
                    }
                ]
            })
        },

and my plugins section has

new ExtractTextPlugin('[name].css?[contenthash]'),

Related