Css-loader: Same file name but different directory, after build hash is same.(use css module)

Created on 23 Mar 2017  路  5Comments  路  Source: webpack-contrib/css-loader

Dir1 (test.css)
.input { display: block }
Dir2 (test.css)
.input { display: none }

Webpack loader options
loader: 'style-loader!css-loader?sourceMap&modules&hashPrefix=23&importLoaders=1&localIdentName=[path][name]-[local]--[hash:base64:5]!postcss-loader?sourceMap&sourceComments',

After Build

.test-input--IPxQk { display: block }
.test-input--IPxQk { display: none }

The class name is conflict.

Most helpful comment

I found some workarounds while trying to debug my issue.

This is the code responsible for resolving the localIdentName:

/*
    MIT License http://www.opensource.org/licenses/mit-license.php
    Author Tobias Koppers @sokra
*/
var loaderUtils = require("loader-utils");
var path = require("path");

module.exports = function getLocalIdent(loaderContext, localIdentName, localName, options) {
    if(!options.context)
        options.context = loaderContext.options && typeof loaderContext.options.context === "string" ? loaderContext.options.context : loaderContext.context;
    var request = path.relative(options.context, loaderContext.resourcePath);
    options.content = options.hashPrefix + request + "+" + localName;
    localIdentName = localIdentName.replace(/\[local\]/gi, localName);
    var hash = loaderUtils.interpolateName(loaderContext, localIdentName, options);
    return hash.replace(new RegExp("[^a-zA-Z0-9\\-_\u00A0-\uFFFF]", "g"), "-").replace(/^((-?[0-9])|--)/, "_$1");
};

As you can see, even if you set localIdentName=[path][name]-[local]--[hash:base64:7] the [path] will only be evaluated to the filename only (because the context will be the same/current folder) and that will cause the conflict (eg. files can have the same name).

Workaround 1: Add the context option to your css-loader config and point to the root of your project (or whatever makes sense for you). Now the entire path will be used for generating the hash.

Workaround 2: Define your own resolving function by adding getLocalIdent to your css-loader config (check the Readme for that)

(While this works for me, I don't have much experience with css-loader to make a PR or suggest that this should be the default behaviour)

All 5 comments

I'm having the same issue. I also tried changing localIdentName=[path][name]-[local]--[hash:base64:5] param to diff combinations like:

localIdentName=[path][name]-[local]--[hash:base64:7]
localIdentName=[name]-[local]--[hash:base64:5]
localIdentName=[name]-[local]--[hash:base64:7]

but to no avail. It creates same classes with same hashes (even with 7).

Btw, #413 also talks about same issue

Same problem here (webpack 2)

I found some workarounds while trying to debug my issue.

This is the code responsible for resolving the localIdentName:

/*
    MIT License http://www.opensource.org/licenses/mit-license.php
    Author Tobias Koppers @sokra
*/
var loaderUtils = require("loader-utils");
var path = require("path");

module.exports = function getLocalIdent(loaderContext, localIdentName, localName, options) {
    if(!options.context)
        options.context = loaderContext.options && typeof loaderContext.options.context === "string" ? loaderContext.options.context : loaderContext.context;
    var request = path.relative(options.context, loaderContext.resourcePath);
    options.content = options.hashPrefix + request + "+" + localName;
    localIdentName = localIdentName.replace(/\[local\]/gi, localName);
    var hash = loaderUtils.interpolateName(loaderContext, localIdentName, options);
    return hash.replace(new RegExp("[^a-zA-Z0-9\\-_\u00A0-\uFFFF]", "g"), "-").replace(/^((-?[0-9])|--)/, "_$1");
};

As you can see, even if you set localIdentName=[path][name]-[local]--[hash:base64:7] the [path] will only be evaluated to the filename only (because the context will be the same/current folder) and that will cause the conflict (eg. files can have the same name).

Workaround 1: Add the context option to your css-loader config and point to the root of your project (or whatever makes sense for you). Now the entire path will be used for generating the hash.

Workaround 2: Define your own resolving function by adding getLocalIdent to your css-loader config (check the Readme for that)

(While this works for me, I don't have much experience with css-loader to make a PR or suggest that this should be the default behaviour)

@hugorodrigues thx I will check that solution, we plan to overhaul css-loader in v1.0.0 and address issues like that. Could you post the part of your webpack.config.js with that setup and PR even if for discussion is highly welcome aswell 馃槢

Was this page helpful?
0 / 5 - 0 ratings