css-loader: CSS modules break build if used with `~`

Module not found: Error: Can’t resolve ‘~’

What is the current behavior?

Using a tilde ~ inside a css file causes Can't resolve '~' if css-modules feature is activated:

{
  loader: 'css-loader',
  options: {
    modules: true,
  }
},

If the current behavior is a bug, please provide the steps to reproduce.

The bug can be reproduced this way: (https://github.com/jantimon/css-loader-bug)

git clone https://github.com/jantimon/css-loader-bug.git
cd css-loader-bug
npm install
npm run without-modules 
npm run with-modules

Working webpack.config.js Broken webpack.config.js CSS File

What is the expected behavior?

Compilation should work even if modules are set to true.

Motivation

I wrote a loader which adds ~!! to a css file and it does not know if the user is using css-modules: https://github.com/jantimon/iconfont-webpack-plugin/blob/master/lib/postcss-plugin.js#L135-L137

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 12
  • Comments: 15 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Is this considered an inconsistency? I wish I could fix this.

This problem still exists.

I find the reason: https://github.com/webpack-contrib/css-loader/blob/master/lib/processCss.js#L163-L174 If open the css module, the mode is ‘local’, url will reserve the ~,such as:

:local { * { background: url('~assets/my-asset.svg'); } }
// urlToRequest
:local { * { background: url(require('~assets/my-asset.svg')); } }

else the mode is ‘global’, url will recognize the ~ ,https://github.com/webpack/loader-utils/blob/67499ff3d13c13ef455ec0fede90b714fc16d787/lib/urlToRequest.js#L50-L52,and remove the ~,require file as a module.such as:

:global { * { background: url('~assets/my-asset.svg'); } }
// urlToRequest
:global { * { background: url(require('assets/my-asset.svg')); } }

@jantimon we use same logic for resolving urls with modules false/local/global, before we use difference logic for local and global and global was broken (you can’t use ~, !! and etc stuff in url), now it is fixed