Search code examples
csswebpackcss-loadercss-modules

Different css modules with same class names overwrite each other


I'm using webpack and try to use css modules for my theming, for example:

<style lang="scss" module="theme1">
  .header {
    color: red;
  }
</style>

<style lang="scss" module="theme2">
  .header {
    color: blue;
  }
</style>

However, both .header tags get the same localIdentName from css-loader and because of that the second theme overrides the other everytime.
My loader chain: vue-loader, css-loader, sass-loader
My current localIdentName: '[local]_[hash:base64:5]' (neither path nor name result in anything, I just wish there was some sort of [value] tag.


Solution

  • Apparently it's because custom inject names were broken during the v14 -> v15 upgrade from vue-loader.

    Heres the issue on GitHub with more details: https://github.com/vuejs/vue-loader/issues/1578

    Temporary solution (put this in the module options of css-loader):

    {
      localIdentName: '[module]_[local]_[hash:base64:5]',
      getLocalIdent(context, localIdentName, localName) {
        const { resourceQuery, resourcePath } = context;
        const { index, module } = loaderUtils.parseQuery(resourceQuery);
    
        const selector = loaderUtils.interpolateName(context, localIdentName, {
          context: context.rootContext,
          content: resourcePath + resourceQuery + localName,
        })
          .replace(/\[local\]/gi, localName)
          .replace(/\[module\]/gi, typeof module === 'boolean' ? '' : module)
          .replace(/\[index\]/gi, index)
          .replace(new RegExp('[^a-zA-Z0-9\\-_\u00A0-\uFFFF]', 'g'), '-')
          .replace(/^((-?[0-9])|--)/, '_$1');
    
        return selector;
      },
    }