Webpack source-map does not resolve sass imports
Asked Answered
I

3

6

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/

Inland answered 3/10, 2017 at 16:58 Comment(0)
W
4

You have sass-loader there, switch it with:

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

And that would work.

Woodenware answered 9/10, 2017 at 13:3 Comment(2)
Just noted that there is currently a bug github.com/webpack-contrib/sass-loader/issues/351 so that it cannot be used with compressed output, so you have to disable sass source mapping for production build. But it is still much useful! :)Inland
@Inland Indeed, though you probably don't want to have source maps in production since it's more code and builds up in size.Woodenware
L
5

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
                       }
                    }
                ]
            },
        ]
    }
};
Lease answered 14/10, 2017 at 12:36 Comment(0)
W
4

You have sass-loader there, switch it with:

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

And that would work.

Woodenware answered 9/10, 2017 at 13:3 Comment(2)
Just noted that there is currently a bug github.com/webpack-contrib/sass-loader/issues/351 so that it cannot be used with compressed output, so you have to disable sass source mapping for production build. But it is still much useful! :)Inland
@Inland Indeed, though you probably don't want to have source maps in production since it's more code and builds up in size.Woodenware
H
1

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]'),

Howund answered 16/10, 2017 at 12:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.