webpack-contrib / sass-loader

Compiles Sass to CSS
MIT License
3.9k stars 428 forks source link

Sass loader v16 compile issue with resolve-url-loader #1225

Closed mmarton closed 1 month ago

mmarton commented 1 month ago

Bug report

Actual Behavior

Hi!

I have a strange issue when upgrading to sass-loader v16. (I know there is a bc break with the config, but I don't have any config and expected flawless upgrade)

My project has a couple 1000 line scss, everything works fine with v16, and without using the legacy api option, except the import of 1 specific font.

I've created a small reproducer at https://github.com/mmarton/sass-loader-poc

Expected Behavior

ERROR in ./main.scss
Module build failed (from ./node_modules/resolve-url-loader/index.js):
Error: resolve-url-loader: error processing CSS
  expected "base" to be absolute path to a valid directory, got "data:;charset=utf-8,/*%20gloria-hallelujah-latin-400-normal...

How Do We Reproduce?

follow the readme at my repo: https://github.com/mmarton/sass-loader-poc

Please paste the results of npx webpack-cli info here, and mention other relevant information


  System:
    OS: Linux 6.8 Ubuntu 24.04 LTS 24.04 LTS (Noble Numbat)
    CPU: (8) x64 Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
    Memory: 6.87 GB / 15.47 GB
  Binaries:
    Node: 22.1.0 - ~/.nvm/versions/node/v22.1.0/bin/node
    Yarn: 1.22.22 - /usr/bin/yarn
    npm: 10.7.0 - ~/.nvm/versions/node/v22.1.0/bin/npm
  Browsers:
    Chrome: 127.0.6533.88
  Packages:
    css-loader: ^7.1.2 => 7.1.2 
    resolve-url-loader: ^5.0.0 => 5.0.0 
    sass-loader: ^16.0.0 => 16.0.0 
    webpack: ^5.93.0 => 5.93.0 
    webpack-cli: ^5.1.4 => 5.1.4 
alexander-akait commented 1 month ago

Please open an issue in resolve-url-loader, looks like they don't have data: Data URI in source maps

Also I want to say - I think you don't need resolve-url-loader at all, most of libraries allow to set path to assets using variables, better to use it, because parsing source maps and using postcss to change them is very slow

Feel free to feedback

alexander-akait commented 1 month ago

As workaround you can use api: "legacy"

mmarton commented 1 month ago

Hmmm, I've dig deeper, and found out that if I specify the path fully then it works without the legacy settings.

doing this in my main.scss (which is the lib's main setting anyway "main": "index.css"):

-@import '~@fontsource/gloria-hallelujah';
+@import '~@fontsource/gloria-hallelujah/index.css';

This way it compiles without any issue. I have no idea why, but it feels like some BC thing here and not on resolve-url-loader's side.

alexander-akait commented 1 month ago

Weird, it should work without it, can you create a small reproducible repo, maybe bug on sass side, so we need to report about

mmarton commented 1 month ago

I've updated the one I've linked in my first comment Check the readme and main.scss

https://github.com/mmarton/sass-loader-poc

alexander-akait commented 1 month ago

Yeah, it is because of data:, when you have @import '~@fontsource/gloria-hallelujah/index.css'; sass generates source map like:

{
  version: 3,
  sourceRoot: '',
  sources: [ '/home/akait/IdeaProjects/sass-loader-poc/main.scss' ],
  names: [],
  mappings: 'AAAQ'
}

but when you have @import '~@fontsource/gloria-hallelujah'; sass generates:

{
  version: 3,
  sourceRoot: '',
  sources: [
    "data:;charset=utf-8,/*%20gloria-hallelujah-latin-400-normal%20*/%0A@font-face%20%7B%0A%20%20font-family:%20'Gloria%20Hallelujah';%0A%20%20font-style:%20normal;%0A%20%20font-display:%20swap;%0A%20%20font-weight:%20400;%0A%20%20src:%20url(./files/gloria-hallelujah-latin-400-normal.woff2)%20format('woff2'),%20url(./files/gloria-hallelujah-latin-400-normal.woff)%20format('woff');%0A%20%20unicode-range:%20U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;%0A%7D"
  ],
  names: [],
  mappings: 'AAAA;AACA;EACE;EACA;EACA;EACA;EACA;EACA'
}

because resolve-url-loader rewrites urls based on source maps and resolve-url-loader can't be handled properly data URI you got such error

Sorry I can't fix it here because the source map generation happens on the sass side and to be honest I don't know why in one case they generate path, in other case data URI, I think will be great to open an issue and ask them to use file: protocol instead data:

alexander-akait commented 1 month ago

/cc @nex3

nex3 commented 1 month ago

The reason @import '~@fontsource/gloria-hallelujah/index.css' works fine is that it's not being processed by Sass at all. @import rules whose URLs end in .css are interpreted by Sass as plain-CSS @imports, so something else must be handling that at a later stage.

The data: URL appearing here is the documented behavior of ImporterResult.sourceMapUrl:

If [the source map URL] isn't set, it defaults to a data: URL that contains the contents of the loaded stylesheet.

The expectation is that a full-on Importer wants full control over what every URL means, including making it possible for file: URLs not to refer to the literal filesystem. If you want a simpler importer interface that handles filesystem stuff like this automatically, a FileImporter may be a better fit. (It's also a bit more efficient in the embedded host, since it doesn't need to make separate requests for loads or relative canonicalization.)

I've verified locally that adding sourceMapUrl: canonicalUrl here fixes this bug.