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

Closed
wingrunr21 opened this issue Jan 18, 2019 · 14 comments
Closed

Comments

@wingrunr21
Copy link

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.

@alexander-akait
Copy link
Member

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

@wingrunr21
Copy link
Author

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

@alexander-akait
Copy link
Member

@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

@alexander-akait
Copy link
Member

alexander-akait 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
Copy link
Author

@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.

@alexander-akait
Copy link
Member

@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
Copy link
Author

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.

@alexander-akait
Copy link
Member

@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
Copy link
Author

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
Copy link
Author

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

@alexander-akait
Copy link
Member

@wingrunr21 invalid fix and break source maps

@alexander-akait
Copy link
Member

alexander-akait 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

@alexander-akait
Copy link
Member

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 😞

@alexander-akait
Copy link
Member

Let's close in favor #622, source map improvements will be after stable 4 release. postcss has some bugs, we need wait postcss@8. I want to union all source maps problems in one issue

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

2 participants