Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source map is incorrect if passed minimized css code #381

Closed
x-yuri opened this issue Nov 26, 2016 · 9 comments
Closed

Source map is incorrect if passed minimized css code #381

x-yuri opened this issue Nov 26, 2016 · 9 comments

Comments

@x-yuri
Copy link

x-yuri commented Nov 26, 2016

package.json:

{
  "dependencies": {
    "css-loader": "^0.26.0",
    "extract-text-webpack-plugin": "^1.0.1",
    "html-webpack-plugin": "^2.24.1",
    "node-sass": "^3.13.0",
    "sass-loader": "^4.0.2",
    "style-loader": "^0.13.1",
    "webpack": "^1.13.3"
  }

webpack.config.js:

var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './1.js',
    output: {
        path: 'dist',
        filename: 'bundle.js',
    },
    module: {
        loaders: [
            {test: /\.scss$/, loaders: ['style', 'css?sourceMap!sass?sourceMap']},
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'template.ejs',
        }),
    ],
    sassLoader: {
        outputStyle: 'compressed',
    },
};

template.ejs:

<!doctype html>
<html>
<body>

<div></div>

</body>
</html>

1.js:

require('./1.scss');

1.scss

body {
    background: #ddd;
}
div {
    width: 100px;
    height: 100px;
    margin: auto;
    background: #666;
}
$ npm i
$ rm -rf dist/* && ./node_modules/.bin/webpack

After sass-loader we get the following css code:

body{background:#ddd}div{width:100px;height:100px;margin:auto;background:#666}

and mappings:

AAAA,AAAA,IAAI,AAAC,CACD,UAAU,CAAE,IAAK,CACpB,AACD,AAAA,GAAG,AAAC,CACA,KAAK,CAAE,KAAM,CACb,MAAM,CAAE,KAAM,CACd,MAAM,CAAE,IAAK,CACb,UAAU,CAAE,IAAK,CACpB

([0,0](#0)=>[0,0])
    | ([0,0](#0)=>[0,0])
    | ([0,4](#0)=>[0,4])
    | ([0,5](#0)=>[0,4])
    | ([1,4](#0)=>[0,5])
    | ([1,14](#0)=>[0,15])
    | ([1,16](#0)=>[0,16])
    | ([1,21](#0)=>[0,20])
    | ([2,1](#0)=>[0,21])
    | ([3,0](#0)=>[0,21])
    | ([3,0](#0)=>[0,21])
    | ([3,3](#0)=>[0,24])
    | ([3,4](#0)=>[0,24])
    | ([4,4](#0)=>[0,25])
    | ([4,9](#0)=>[0,30])
    | ([4,11](#0)=>[0,31])
    | ([4,17](#0)=>[0,36])
    | ([5,4](#0)=>[0,37])
    | ([5,10](#0)=>[0,43])
    | ([5,12](#0)=>[0,44])
    | ([5,18](#0)=>[0,49])
    | ([6,4](#0)=>[0,50])
    | ([6,10](#0)=>[0,56])
    | ([6,12](#0)=>[0,57])
    | ([6,17](#0)=>[0,61])
    | ([7,4](#0)=>[0,62])
    | ([7,14](#0)=>[0,72])
    | ([7,16](#0)=>[0,73])
    | ([7,21](#0)=>[0,77])
    | ([8,1](#0)=>[0,78])

which are pretty fine to me.

But after css-loader what we got are the same css code, but different mappings:

AAAA,KACI,eAAiB,CACpB,IAEG,YACA,aACA,YACA,eAAiB,CACpB

([0,0](#0)=>[0,0])
    | ([1,4](#0)=>[0,5])
    | ([1,21](#0)=>[0,20])
    | ([2,1](#0)=>[0,21])
    | ([4,4](#0)=>[0,25])
    | ([5,4](#0)=>[0,37])
    | ([6,4](#0)=>[0,50])
    | ([7,4](#0)=>[0,62])
    | ([7,21](#0)=>[0,77])
    | ([8,1](#0)=>[0,78])

and Chrome reports the wrong line (no mapping for line 4 above in terms of Chrome):

css-loader

P.S. node-7.1.0, Arch Linux

@x-yuri x-yuri changed the title source map is incorrect if passed minimized css code Source map is incorrect if passed minimized css code Nov 26, 2016
@michael-ciniawsky
Copy link
Member

@x-yuri Does this still happen with latest css-loader && webpack 2? Could you provide more info about your setup?

@x-yuri
Copy link
Author

x-yuri commented May 23, 2017

@michael-ciniawsky Yes, it reproduces with webpack-2.x. Here are the changed files:

package.json

{
  "dependencies": {
    "css-loader": "^0.28.2",
    "html-webpack-plugin": "^2.28.0",
    "node-sass": "^4.5.3",
    "sass-loader": "^6.0.5",
    "style-loader": "^0.18.1",
    "webpack": "^2.6.0"
  }
}

webpack.config.js

var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './1.js',
    output: {
        path: path.resolve('dist'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {test: /\.scss$/, use: [
                'style-loader',
                {loader: 'css-loader', options: {sourceMap: true}},
                {loader: 'sass-loader', options: {sourceMap: true, outputStyle: 'compressed'}},
            ]},
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'template.ejs',
        }),
    ],
};

With this, chrome points at line 5. But when you set outputStyle: 'nested' (default value), it points at line 4, as it's supposed to be.

Could you provide more info about your setup?

Just tell me what exactly is it you want to know. I believe I've described everything I possibly could.

@alexander-akait
Copy link
Member

@x-yuri Not related to css-loader. Original issue: webpack-contrib/sass-loader#272. Thanks!

@x-yuri
Copy link
Author

x-yuri commented May 23, 2017

@evilebottnawi Where do you see nested styles in 1.scss?

@alexander-akait
Copy link
Member

@x-yuri this bug related to change outputStyle in sass-loader.

@x-yuri
Copy link
Author

x-yuri commented May 24, 2017

@evilebottnawi I see nothing wrong with what sass-loader produces:

body{background:#ddd}div{width:100px;height:100px;margin:auto;background:#666}

/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RkaW4uY3NzIiwic291cmNlUm9vdCI6Ii9zcnYvaHR0cC9zMS93cC8xIiwic291cmNlcyI6WyJzdGRpbiJdLCJzb3VyY2VzQ29udGVudCI6WyJib2R5IHtcbiAgICBiYWNrZ3JvdW5kOiAjZGRkO1xufVxuZGl2IHtcbiAgICB3aWR0aDogMTAwcHg7XG4gICAgaGVpZ2h0OiAxMDBweDtcbiAgICBtYXJnaW46IGF1dG87XG4gICAgYmFja2dyb3VuZDogIzY2Njtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxBQUFBLElBQUksQUFBQyxDQUNELFVBQVUsQ0FBRSxJQUFJLENBQ25CLEFBQ0QsQUFBQSxHQUFHLEFBQUMsQ0FDQSxLQUFLLENBQUUsS0FBSyxDQUNaLE1BQU0sQ0FBRSxLQUFLLENBQ2IsTUFBTSxDQUFFLElBQUksQ0FDWixVQUFVLENBQUUsSUFBSSxDQUNuQiJ9 */

Open this link, paste the code above into Output field, click Analyze and use Right/Left arrows to navigate.

Let's just say, css-loader can't handle what libsass produces. Or probably cssnano. css-loader itself doesn't change source map in any way, right? So at fault is either libsass, or cssnano.

@JiDai
Copy link

JiDai commented Jan 24, 2018

I have the same problem, did you find any solution ?

@x-yuri
Copy link
Author

x-yuri commented Jan 25, 2018

I've just rechecked my test case. I can reproduce it with Webpack 1, 2, and 3. Steps to reproduce:

$ yarn
$ rm -rf dist/* && ./node_modules/.bin/webpack

And display styles for div in Chromium. Chromium 63.0.3239.132 (Developer Build) (64-bit) in my case. These days the block points to 5th line.


Which is still wrong :) But inspecting resulting css:

body{background:#ddd}div{width:100px;height:100px;margin:auto;background:#666}                 
                                                                                               
/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9zcnYvaHR0cC9zMS9teS13ZWJwYWNrLTMvMS5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLEtBQ0ksZUFBZ0IsQ0FDbkIsSUFFRyxZQUNBLGFBQ0EsWUFDQSxlQUFnQixDQUNuQiIsImZpbGUiOiIxLnNjc3MiLCJzb3VyY2VzQ29udGVudCI6WyJib2R5IHtcbiAgICBiYWNrZ3JvdW5kOiAjZGRkO1xufVxuZGl2IHtcbiAgICB3aWR0aDogMTAwcHg7XG4gICAgaGVpZ2h0OiAxMDBweDtcbiAgICBtYXJnaW46IGF1dG87XG4gICAgYmFja2dyb3VuZDogIzY2Njtcbn1cbiJdLCJzb3VyY2VSb290IjoiIn0= */

here (put css into Output field and click Analyze, then use Left/Right arrows, more on it here) shows that there're not many options for a browser to choose from. No mapping to line 4 exists in the resulting source map. But if we take libsass's result:

body{background:#ddd}div{width:100px;height:100px;margin:auto;background:#666}

/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9zcnYvaHR0cC9zMS9teS13ZWJwYWNrLTMvMS5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLEFBQUEsSUFBSSxBQUFDLENBQ0QsVUFBVSxDQUFFLElBQUksQ0FDbkIsQUFDRCxBQUFBLEdBQUcsQUFBQyxDQUNBLEtBQUssQ0FBRSxLQUFLLENBQ1osTUFBTSxDQUFFLEtBQUssQ0FDYixNQUFNLENBQUUsSUFBSSxDQUNaLFVBQVUsQ0FBRSxJQUFJLENBQ25CIiwiZmlsZSI6IjEuc2NzcyIsInNvdXJjZXNDb250ZW50IjpbImJvZHkge1xuICAgIGJhY2tncm91bmQ6ICNkZGQ7XG59XG5kaXYge1xuICAgIHdpZHRoOiAxMDBweDtcbiAgICBoZWlnaHQ6IDEwMHB4O1xuICAgIG1hcmdpbjogYXV0bztcbiAgICBiYWNrZ3JvdW5kOiAjNjY2O1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ== */

That's a different story.

@evilebottnawi So you're saying it's source-map package that is at fault here... I hope I'll find time to investigate it.

@JiDai I've switched to postcss. But for a different reason.

@x-yuri
Copy link
Author

x-yuri commented Jan 26, 2018

Well, it turns out even with libsass's result Chromium these days doesn't point to line 4:

1.scss:

body {
    background: #ddd;
}
div {
    width: 100px;
    height: 100px;
    margin: auto;
    background: #666;
}
$ yarn add node-sass
$ ./node_modules/.bin/node-sass --output-style compressed --source-map true --source-map-contents 1.scss 1.css

index.html:

<!doctype html>
<html>
<body>
<link rel="stylesheet" href="1.css">

<div></div>

</body>
</html>

1.css:

body{background:#ddd}div{width:100px;height:100px;margin:auto;background:#666}

/*# sourceMappingURL=1.css.map */

1.css.map:

{
	"version": 3,
	"file": "1.css",
	"sources": [
		"1.scss"
	],
	"sourcesContent": [
		"body {\n    background: #ddd;\n}\ndiv {\n    width: 100px;\n    height: 100px;\n    margin: auto;\n    background: #666;\n}\n"
	],
	"names": [],
	"mappings": "AAAA,AAAA,IAAI,AAAC,CACD,UAAU,CAAE,IAAI,CACnB,AACD,AAAA,GAAG,AAAC,CACA,KAAK,CAAE,KAAK,CACZ,MAAM,CAAE,KAAK,CACb,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,IAAI,CACnB"
}

If we now create a copy of 1.scss (2.css), and make index.html use it. We can see that Chromium puts the cursor after the opening curly bracket (div {). Then with this amended source map, which has extra segment referring to the position after the bracket:

3.css.map

{
	"version": 3,
	"file": "1.css",
	"sources": [
		"1.scss"
	],
	"sourcesContent": [
		"body {\n    background: #ddd;\n}\ndiv {\n    width: 100px;\n    height: 100px;\n    margin: auto;\n    background: #666;\n}\n"
	],
	"names": [],
	"mappings": "AAAA,AAAA,IAAI,AAAC,CACD,UAAU,CAAE,IAAI,CACnB,AACD,AAAA,GAAG,AAAC,CAAC,CACD,KAAK,CAAE,KAAK,CACZ,MAAM,CAAE,KAAK,CACb,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,IAAI,CACnB"
}

It works. Chromium refers to line 4.

So, it must be safe to assume, that the issue has been resolved on the browsers' end. They choose next segment after the bracket.

It's only the fact that source-map package negates libsass' efforts that's still bugging me... :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants