webpack-contrib/css-loader

urls are broken when using sourceMaps

timaschew opened this issue ยท 14 comments

I have this loader

      {
        test: /\.css$/,
        loader: 'style!css?sourceMap'
      }

and import font-awesome with this statement:
@import "~font-awesome/css/font-awesome.css";

Its working fine and the font url looks like this

@font-face {
  font-family: 'FontAwesome';
  src: url(/assets/32400f4e08932a94d8bfd2422702c446.eot);

But when I enable source maps via

      {
        test: /\.css$/,
        loader: 'style!css?sourceMap'
      }

It's not working anymore and the font url become

@font-face {
  font-family: 'FontAwesome';
  src: url('../fonts/fontawesome-webfont.eot?v=4.5.0');

I was having this issue.

Setting config.output.publicPath to an absolute url (including domain) resulted in urls (and source maps) being generated properly

config.output.publicPath = 'http://localhost:3001/';

@JakeElder Great job! There is a same solution on stackoverflow.

Thanks @JakeElder

It would be great if we could have relative paths and sourceMaps. My application is deployed to various subdomains and creating a build for each is not very viable.

Has anyone figured out exactly why this broke? I ran into this issue while updating dependencies this morning, but I'm not sure which update did it. I'll try downgrading some packages and see what happens (fyi, hadn't updated css-loader until I ran into this issue).

It took me several days to finally stumble upon this issue. My only option right now is to disable sourceMap for css.

This issue manifested itself as a very, very long list of HTTP requests, such as

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/%5C%22../scss/_variables%5C%22
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/%5C%22~bootstrap/scss/variables%5C%22
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/%5C%22~bootstrap/scss/mixins%5C%22
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/scss/variables%5C%22
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/%5C%22../scss/variables%5C%22
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/%5C%22~bootstrap/scss/_variables%5C%22

Heya, I've been trying to figure out what's happening here and I'm beginning to think it's actually working as intended...

css-loader does send the sourcemaps correctly to style-loader, but in it's docs it clearly says that you need the output.publicPath to be set:
https://github.com/webpack-contrib/style-loader#recommended-configuration

Note about source maps support and assets referenced with url: when style loader is used with ?sourceMap option, the CSS modules will be generated as Blobs, so relative paths don't work (they would be relative to chrome:blob or chrome:devtools). In order for assets to maintain correct paths setting output.publicPath property of webpack configuration must be set, so that absolute paths are generated.

It is not working as intended. Enabling of source maps should not produce the bad output. Source maps separately, generated code separately. Relative paths may not work in source maps themselves, but it should not affect the code.

FWIW, I think this is a problem with css-loader being used in conjunction with webpack-dev-server. Both webpack-dev-server and React starter kit use Express, however the React Starter Kit has no issues with sourcemaps in their implementation.

On regular build it behaves the same way.

@filipesilva Thanks! I spent so much time trying to figure out why assets are not loaded when source maps are enabled. Unfortunately, having to set publicPath is not very convenient, because if I simply set it to http://localhost:${PORT}/ I won't be able to access it from other devices.

@szimek adding publicPath: '' to extract-text-plugin should be enough to have sourcemaps and correct urls while extracting.

There's another option - replace style-loader with vue-style-loader. It works fine for me.

Fixed the issue that root-relative URLs are interpreted against chrome:// urls and make source map URLs work for injected <style> tags in Chrome.

rules: [
  {
    test: /\.css$/,
    use: ['vue-style-loader', 'css-loader?sourceMap']
  }
]

@chatii2412 Thank you! I thought that it's impossible to provide source maps when styles are inside <style> tag and that's why style-loader is using a blob.