diff --git a/lib/loader.js b/lib/loader.js index ac875159..6574b0a7 100644 --- a/lib/loader.js +++ b/lib/loader.js @@ -27,7 +27,7 @@ function sassLoader(content) { const resourcePath = this.resourcePath; function addNormalizedDependency(file) { - // node-sass returns UNIX-style paths + // node-sass returns POSIX paths self.dependency(path.normalize(file)); } @@ -57,8 +57,12 @@ function sassLoader(content) { result.map.file = resourcePath; // The first source is 'stdin' according to libsass because we've used the data input // Now let's override that value with the correct relative path - result.map.sources[0] = path.relative(self.options.context, resourcePath); - result.map.sourceRoot = path.relative(self.options.context, process.cwd()); + result.map.sources[0] = path.basename(resourcePath); + result.map.sourceRoot = path.dirname(resourcePath); + // node-sass returns POSIX paths, that's why we need to transform them back to native paths. + // This fixes an error on windows where the source-map module cannot resolve the source maps. + // @see https://github.com/jtangelder/sass-loader/issues/366#issuecomment-279460722 + result.map.sources = result.map.sources.map(path.normalize); } else { result.map = null; } diff --git a/package.json b/package.json index 109585bb..8cabb20e 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,10 @@ "scripts": { "create-spec": "node test/tools/runCreateSpec.js", "pretest": "node test/tools/runCreateSpec.js", - "test": "mocha -R spec", + "test": "mocha -R spec -t 10000", "posttest": "eslint --fix lib test", "test-bootstrap-sass": "webpack-dev-server --config test/bootstrapSass/webpack.config.js --content-base ./test/bootstrapSass", - "test-source-map": "webpack-dev-server --config test/sourceMap/webpack.config.js --content-base ./test/sourceMap", + "test-source-map": "webpack-dev-server --config test/sourceMap/webpack.config.js --content-base ./test/sourceMap --inline", "test-watch": "webpack --config test/watch/webpack.config.js", "test-extract-text": "webpack --config test/extractText/webpack.config.js", "test-hmr": "webpack-dev-server --config test/hmr/webpack.config.js --content-base ./test/hmr --hot --inline" diff --git a/test/index.test.js b/test/index.test.js index 4b9911b5..50c1b8c4 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -113,7 +113,7 @@ describe("sass-loader", () => { ] }] } - }, (err) => err ? reject(err) : resolve()); + }, err => err ? reject(err) : resolve()); }) .then(() => { const expectedCss = readCss("scss", "imports"); @@ -137,6 +137,34 @@ describe("sass-loader", () => { }) ); }); + describe("source maps", () => { + it("should compile without errors", () => + new Promise((resolve, reject) => { + runWebpack({ + entry: path.join(__dirname, "scss", "imports.scss"), + // We know that setting a custom context can confuse webpack when resolving source maps + context: path.join(__dirname, "scss"), + output: { + filename: "bundle.source-maps.compile-without-errors.js" + }, + devtool: "source-map", + module: { + rules: [{ + test: /\.scss$/, + use: [ + { loader: "css-loader", options: { + sourceMap: true + } }, + { loader: pathToSassLoader, options: { + sourceMap: true + } } + ] + }] + } + }, err => err ? reject(err) : resolve()); + }) + ); + }); describe("errors", () => { it("should throw an error in synchronous loader environments", () => { try { @@ -209,8 +237,8 @@ function runWebpack(baseConfig, done) { webpack(webpackConfig, (webpackErr, stats) => { const err = webpackErr || - (stats.hasErrors && stats.compilation.errors[0]) || - (stats.hasWarnings && stats.compilation.warnings[0]); + (stats.hasErrors() && stats.compilation.errors[0]) || + (stats.hasWarnings() && stats.compilation.warnings[0]); done(err || null); }); diff --git a/test/scss/imports.scss b/test/scss/imports.scss index 540283c5..97635bd9 100644 --- a/test/scss/imports.scss +++ b/test/scss/imports.scss @@ -13,3 +13,7 @@ @import "~animate.css/animate"; /* @import url(http://example.com/something/from/the/interwebs); */ @import url(http://example.com/something/from/the/interwebs); +/* scoped import @import "language"; */ +.scoped-import { + @import "language"; +} diff --git a/test/sourceMap/entry.js b/test/sourceMap/entry.js deleted file mode 100644 index a0ddeb39..00000000 --- a/test/sourceMap/entry.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; - -require("../scss/multiple-imports.scss"); diff --git a/test/sourceMap/index.html b/test/sourceMap/index.html index 843f35b8..538f2d6f 100644 --- a/test/sourceMap/index.html +++ b/test/sourceMap/index.html @@ -3,9 +3,9 @@ - + - +

Open the developer tools, dude!

diff --git a/test/sourceMap/webpack.config.js b/test/sourceMap/webpack.config.js index 973998e7..8fe34265 100644 --- a/test/sourceMap/webpack.config.js +++ b/test/sourceMap/webpack.config.js @@ -4,10 +4,9 @@ const path = require("path"); const sassLoader = require.resolve("../../lib/loader"); module.exports = { - entry: path.resolve(__dirname, "./entry.js"), + entry: path.resolve(__dirname, "..", "scss", "imports.scss"), output: { - path: path.resolve(__dirname, "../output"), - filename: "bundle.sourceMap.js" + filename: "bundle.js" }, devtool: "source-map", module: {