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

Setting sourceMap: true generates different content hashes on Linux vs MacOS #886

Open
wingrunr21 opened this issue Jan 18, 2019 · 13 comments
Open

Comments

@wingrunr21
Copy link

@wingrunr21 wingrunr21 commented Jan 18, 2019

  • Operating System: MacOS and Linux
  • Node Version: Tested on 9.x and 10.x
  • NPM Version: 6.1.0
  • webpack Version: ^4.28.4
  • css-loader Version: ^2.1.0

Expected Behavior

The generated contenthash for a CSS file is consistent with the content of the file.

Actual Behavior

The generated contenthash differs depending on which operating system Webpack is run on.

I have tried various combinations of adding removing loaders before/after the css-loader (including using style-loader instead of MiniCssExtractPlugin) and the addition/removal of the sourceMap option in css-loader is the thing that triggers this to occur.

The files in the various operating systems have the exact same content. This was verified by generating an MD5 hash of the CSS file.

Code

// webpack.config.good.js
{
  test: /\.s?css$/,
  use: [
    MiniCssExtractPlugin.loader,
      {
        loader: "css-loader"
      },
    { loader: "sass-loader", options: { sourceMap: true } }
  ]
}

// webpack.config.bad.js
{
  test: /\.s?css$/,
  use: [
    MiniCssExtractPlugin.loader,
      {
        loader: "css-loader",
        options: { sourceMap: true }
      },
    { loader: "sass-loader", options: { sourceMap: true } }
  ]
}

How Do We Reproduce?

Please see my example repo

There's a CircleCI build configured where you can see the "good" and "bad" webpack config running. If you take a look at the generated contenthash (and compare against a compilation on a Mac), you can see they are different

For my Mac, the "good" output is main.faf79bb5bf2915fa1fb9.css and the "bad" output is main.a2f311c836bf5e7db183.css.

Contrast this with the Linux build in CircleCI:
"good" output is main.faf79bb5bf2915fa1fb9.css as expected
"bad" output is main.64ea49633b59dce4de34.css which differs from the MacOS build.

@evilebottnawi

This comment has been minimized.

Copy link
Member

@evilebottnawi evilebottnawi commented Jan 18, 2019

Thanks for issue, i will investigate this in near future, but i think problem not in css-loader

@wingrunr21

This comment has been minimized.

Copy link
Author

@wingrunr21 wingrunr21 commented Jan 18, 2019

It is very possible the problem is in Webpack itself. I looked through the code for css-loader and didn't see anything that could potentially be causing this.

Note I have not tried this in Webpack v5 alpha as MiniCssExtractPlugin and HtmlWebpackPlugin are not yet compatible

@evilebottnawi

This comment has been minimized.

Copy link
Member

@evilebottnawi evilebottnawi commented Jan 22, 2019

@wingrunr21 after investigate i find problem:

With sourceMap: true css-loader generate:

exports = module.exports = require("../node_modules/css-loader/dist/runtime/api.js")(true);
// Module
exports.push([module.id, "body{background-color:gray}\n", "",{"version":3,"sources":["/home/evilebottnawi/IdeaProjects/webpack-css-contenthash-different/src/src/app.scss"],"names":[],"mappings":"AAAA,KACE,qBAAsB","file":"app.scss","sourcesContent":["body {\n  background-color: gray;\n}"],"sourceRoot":""}]);

Without

exports = module.exports = require("../node_modules/css-loader/dist/runtime/api.js")(false);
// Module
exports.push([module.id, "body{background-color:gray}\n", ""]);

So content hashes are difference. Problem on side mini-css-extract-plugin here https://github.com/webpack-contrib/mini-css-extract-plugin/blob/ffb0d87ce68560e2b301a090d257c105f60a969a/src/index.js#L96

We should respect sourceMap option for mini-css-extract-plugin. Open issue #886, feel free to send a PR

@evilebottnawi

This comment has been minimized.

Copy link
Member

@evilebottnawi evilebottnawi commented Jan 22, 2019

You can comment

hash.update(this.sourceMap ? JSON.stringify(this.sourceMap) : '');

And see what contenthash is same.
Just need like:

if (pluginOptions.sourceMap) {
  hash.update(this.sourceMap ? JSON.stringify(this.sourceMap) : '');
}
@wingrunr21

This comment has been minimized.

Copy link
Author

@wingrunr21 wingrunr21 commented Jan 23, 2019

@evilebottnawi I don't believe that will fix the problem:

A) doesn't the ternary already respect the sourceMap option?
B) Even with that, the sourcemaps are still different on the various operating systems. I think the issue is from the sources array in the sourcemap object. That path is an absolute path, not a relative path, so it could be different from machine to machine. This causes the contenthash to be different.

@evilebottnawi

This comment has been minimized.

Copy link
Member

@evilebottnawi evilebottnawi commented Jan 23, 2019

@wingrunr21

doesn't the ternary already respect the sourceMap option?
No, we should fix it in plugin

Even with that, the sourcemaps are still different on the various operating systems. I think the issue is from the sources array in the sourcemap object. That path is an absolute path, not a relative path, so it could be different from machine to machine. This causes the contenthash to be different.

#652

Unfortunately we have problems with source maps and paths in sass-loader, postcss-loader and css-loader, you can help us.

@wingrunr21

This comment has been minimized.

Copy link
Author

@wingrunr21 wingrunr21 commented Jan 23, 2019

I can try to dig into this but it looks like this has been reported for awhile. Would you mind re-opening this issue as it is not in fact resolved.

@evilebottnawi

This comment has been minimized.

Copy link
Member

@evilebottnawi evilebottnawi commented Jan 23, 2019

@wingrunr21
I think we should use relative paths for sources in source map and always use linux path, need tests how it is works (include windows)

@wingrunr21

This comment has been minimized.

Copy link
Author

@wingrunr21 wingrunr21 commented Jan 23, 2019

Yep, that seems right. I'll see if I have time to dig into it. Looks like there are a few example repos with reproduction steps.

@wingrunr21

This comment has been minimized.

Copy link
Author

@wingrunr21 wingrunr21 commented Jan 29, 2019

@evilebottnawi Upon looking at this closer, fixes across the various loaders have been submitted already. #753 addresses it for this project

@evilebottnawi

This comment has been minimized.

Copy link
Member

@evilebottnawi evilebottnawi commented Jan 29, 2019

@wingrunr21 invalid fix and break source maps

@evilebottnawi

This comment has been minimized.

Copy link
Member

@evilebottnawi evilebottnawi commented Mar 6, 2019

To solve this problem we should:

  • normalize path in sources, sourceRoot and file in source map (done)
  • use relative paths (will be done in sass-loader in next release)
  • add check on sourceMap in mini-css-extract-plugin or maybe pass undefined instead empty string when source map is not present
@evilebottnawi evilebottnawi mentioned this issue Mar 6, 2019
2 of 6 tasks complete
@evilebottnawi

This comment has been minimized.

Copy link
Member

@evilebottnawi evilebottnawi commented Dec 26, 2019

Working on this problem #1031, found what it is happens only with sass-loader and sourceMap: true, sorry for big delay in this issue, a lot of issues 😞

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

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.