sass-loader: includePaths do not work with Webpack 2

Hi everyone, I am using Windows 10 x64 and Webpack 2, with sass-loader version 4.1.1 , but can’t use standard syntax

use: [
    {loader: 'style-loader'},
    {
        loader: 'css-loader',
        options: {
            sourceMap: true
        }
    },
    {
        loader: 'sass-loader',
        options: {
            includePaths: [
                path.resolve(__dirname, 'vendor/zurb/foundation/scss'),
                path.resolve(__dirname, 'node_modules/motion-ui/src'),
                path.resolve(__dirname, 'resources/assets/sass')
            ],
            sourceMap: true
  
        }
    }
]

The only way to get this to work is to use LoaderOptionsPlugin

new webpack.LoaderOptionsPlugin({
    options: {
        context: '/', // <- putting this line right under "options" did the trick
        sassLoader: {
            includePaths: [
                path.resolve(__dirname, 'vendor/zurb/foundation/scss'),
                path.resolve(__dirname, 'node_modules/motion-ui/src'),
                path.resolve(__dirname, 'resources/assets/sass')
            ]
        }
    }
})

Otherwise it throws an error saying can’t import ‘foundation’ and so on. LoaderOptionsPlugin stops to work as of version 5.0.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 8
  • Comments: 32 (12 by maintainers)

Commits related to this issue

Most upvoted comments

The sass-loader has its own loader pipeline. This configuration fixed the issue:

            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        scss: 'vue-style-loader!css-loader!sass-loader?' + JSON.stringify({
                            includePaths: [
                                path.resolve(__dirname, 'node_modules/foundation-sites/scss'),
                            ]
                        }), // <style lang="scss">
                        sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' // <style lang="sass">
                    }
                }
            }

This is my config and it’s working with your sass-loader-test repository

const webpack = require('webpack')
const path = require('path')
// noinspection JSUnresolvedFunction
module.exports = {
    entry: [
        'babel-polyfill',
        'webpack/hot/dev-server',
        // ?reload=true enables full page reload on hmr failure
        'webpack-hot-middleware/client?reload=true',
        './app'
    ],
    context: path.resolve(__dirname, 'resources/assets/js'),
    output: {
        path: path.resolve(__dirname, 'public/js'),
        filename: 'app.js',
        publicPath: '/js/'
    },
    devtool: 'eval-source-map',
    module: {
        rules: [
            {
                enforce: 'pre',
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/
            },
            {
                enforce: 'pre',
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                query: {
                    presets: ['es2015'],
                    plugins: ['lodash']
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        scss: 'vue-style-loader!css-loader!sass-loader?' + JSON.stringify({
                            includePaths: [
                                path.resolve(__dirname, 'node_modules/foundation-sites/scss'),
                            ]
                        }), // <style lang="scss">
                        sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' // <style lang="sass">
                    }
                }
            },
            {
                test: /\.scss$/,
                use: [
                    {loader: 'style-loader'},
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: true,
                            includePaths: [
                                path.resolve(__dirname, 'node_modules/foundation-sites/scss'),
                            ]
                        }
                    }
                ]
            }
        ]
    },
    resolve: {
        alias: {
            'inputmask.dependencyLib': path.resolve(__dirname, 'node_modules/jquery.inputmask/extra/dependencyLibs/inputmask.dependencyLib/'),
            'inputmask': path.resolve(__dirname, 'node_modules/jquery.inputmask/dist/inputmask/inputmask/')
        },
        extensions: ['.webpack.js', '.web.js', '.tsx', '.ts', '.js']
    },
    // watchOptions: {
    //     poll: 1000 // <-- it's worth setting a timeout to prevent high CPU load
    // },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        // new webpack.LoaderOptionsPlugin({
        //     options: {
        //         context: '/', // <- putting this line right under "options" did the trick
        //         sassLoader: {
        //             includePaths: [
        //                 path.resolve(__dirname, 'vendor/zurb/foundation/scss'),
        //                 path.resolve(__dirname, 'node_modules/motion-ui/src'),
        //                 path.resolve(__dirname, 'resources/assets/sass')
        //             ]
        //         }
        //     }
        // })
    ]
}
sass-loader-test master ✗ 5bbf397 6d △ ➜ webpack -v
2.2.1
sass-loader-test master ✗ 5bbf397 6d △ ➜ webpack 
(node:6034) DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic, see https://github.com/webpack/loader-utils/issues/56
parseQuery() will be replaced with getOptions() in the next major version of loader-utils.
Hash: b984fcd717d3b5867277
Version: webpack 2.2.1
Time: 2794ms
 Asset     Size  Chunks                    Chunk Names
app.js  1.62 MB       0  [emitted]  [big]  main
  [87] (webpack)/buildin/global.js 509 bytes {0} [built]
 [120] /Users/jhnns/dev/temp/sass-loader-test/~/vue/dist/vue.runtime.esm.js 174 kB {0} [built]
 [121] ./app.js 305 bytes {0} [built]
 [122] /Users/jhnns/dev/temp/sass-loader-test/~/babel-polyfill/lib/index.js 833 bytes {0} [built]
 [123] (webpack)-hot-middleware/client.js?reload=true 6.68 kB {0} [built]
 [124] (webpack)/hot/dev-server.js 1.57 kB {0} [built]
 [127] /Users/jhnns/dev/temp/sass-loader-test/~/core-js/fn/regexp/escape.js 107 bytes {0} [built]
 [307] /Users/jhnns/dev/temp/sass-loader-test/~/core-js/shim.js 7.38 kB {0} [built]
 [314] /Users/jhnns/dev/temp/sass-loader-test/~/querystring-es3/index.js 127 bytes {0} [built]
 [316] /Users/jhnns/dev/temp/sass-loader-test/~/strip-ansi/index.js 161 bytes {0} [built]
 [318] ../sass/app.scss 1.12 kB {0} [built]
 [319] ./App.vue 1.57 kB {0} [built]
 [325] (webpack)-hot-middleware/client-overlay.js 1.82 kB {0} [built]
 [329] (webpack)/hot/log-apply-result.js 1.02 kB {0} [built]
 [330] multi babel-polyfill webpack/hot/dev-server webpack-hot-middleware/client?reload=true ./app 64 bytes {0} [built]
    + 316 hidden modules
sass-loader-test master ✗ 5bbf397 6d △ ➜ 

@jhnns hey just tested options: { includePaths: [...] } with sass-loader@6.0.2 and it worked fine. I think this may be ok to close 👍 .

No problem. You’re welcome 😃

I’m willing to help if the other side is providing a test repository. This makes spotting bugs/wrong configurations a lot easier.

@asolopovas with sass-loader 4.1.1 and webpack 2.2.1, both config examples work.

With sass-loader 5.0.1, webpack.config.js does not work because the sass-loader doesn’t read the config from the webpack options object anymore. You don’t need to use the LoaderOptionsPlugin with sass-loader 5.0.0 anymore. Just specify the loader options directly. Thus, webpack.config.error.js does work.

@asolopovas Same issue here after upgrading to 5.0.0. Your suggested solution did not fix mine elas… Rolled back to 4.1.1 and issue disappeared.

A hack solution is definitely better then no solution thanks

Oh, I don’t think that this is a hack solution. Since a vue file can host a lot of file types, it makes sense to have a dedicated loader pipeline because webpack’s loader test algorithm wouldn’t work here.

@janusch Could you try the latest sass-loader on master branch? If it’s still not working, you can try to comment out these lines. Does it work then? How do the paths look like when they come from node-sass?

Ok, now I can reproduce this error on Windows (doesn’t happen on macOS):

ERROR in E:/temp/sass-loader-test/~/css-loader?{"sourceMap":true}!E:/temp/sass-loader-test/~/sass-loader/lib/loader.js?{"sourceMap":true,"includePaths":["E://temp//sass-loader-test//~//foundation-sites//scss","E://temp//sass-loader-test//~//motion-ui//src","E://temp//sass-loader-test//resources//assets//sass"]}!../sass/app.scss
Module build failed: Error: "../../node_modules/foundation-sites/scss/foundation.scss" is not in the SourceMap.
    at BasicSourceMapConsumer.SourceMapConsumer_sourceContentFor [as sourceContentFor] (E:\temp\sass-loader-test\node_modules\source-map\lib\source-map-consumer.js:704:13)
    at SourceMapGenerator.<anonymous> (E:\temp\sass-loader-test\node_modules\source-map\lib\source-map-generator.js:235:40)
    at Array.forEach (native)
    at SourceMapGenerator_applySourceMap [as applySourceMap] (E:\temp\sass-loader-test\node_modules\source-map\lib\source-map-generator.js:234:32)
    at MapGenerator.applyPrevMaps (E:\temp\sass-loader-test\node_modules\postcss\lib\map-generator.js:146:22)
    at MapGenerator.generateMap (E:\temp\sass-loader-test\node_modules\postcss\lib\map-generator.js:194:46)
    at MapGenerator.generate (E:\temp\sass-loader-test\node_modules\postcss\lib\map-generator.js:297:25)
    at LazyResult.stringify (E:\temp\sass-loader-test\node_modules\postcss\lib\lazy-result.js:296:24)
    at E:\temp\sass-loader-test\node_modules\postcss\lib\lazy-result.js:233:27
    at process._tickCallback (internal/process/next_tick.js:103:7)
 @ ../sass/app.scss 4:14-151
 @ ./app.js
 @ multi ./app

It seems like node-sass is exporting source maps with forward slashes (which are also valid on Windows). Webpack’s source map module, however, stores backslash paths. That’s why the source maps can not be resolved.

I can fix this in sass-loader by applying path.normalize on all source map paths.

Next time, please always post the actual error message including the stack trace.

Thank you. I use LoaderOptionsPlugin and rollback sass-loader to 4.1.1. It work.

@asolopovas includePaths work fine for me in 4.1.1: new webpack.LoaderOptionsPlugin({ options: { sassLoader: { includePaths: [ path.resolve(__dirname, '../src/app/assets/sass'), path.resolve(__dirname, '../node_modules/bootstrap/scss') ] } } })