webpack-contrib / sass-loader

Compiles Sass to CSS
MIT License
3.91k stars 427 forks source link

With "modern" API, the `importer` behaves strangely with nested imports #1237

Open adrienharnay opened 1 week ago

adrienharnay commented 1 week ago

Modification Proposal

I believe there are some quirks in the current importer implementation that limit possible use cases. One of these use cases is to import JSON files with sass or embedded-sass implementations.

Expected Behavior / Situation

Here is a minimal reproduction with steps to understand the limitations and changes needed to make the importer work.

From the README:

I remain available to exchange on the topic, having spent a few hours browsing and debugging the code.

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

System:
    OS: macOS 14.6.1
    CPU: (8) arm64 Apple M1 Pro
    Memory: 57.83 MB / 16.00 GB
  Binaries:
    Node: 22.9.0 - /usr/local/bin/node
    Yarn: 4.5.0 - /opt/homebrew/bin/yarn
    npm: 10.8.3 - /usr/local/bin/npm
  Browsers:
    Chrome: 129.0.6668.100
    Safari: 17.6
  Packages:
    css-loader: ^7.1.2 => 7.1.2 
    sass-loader: ^16.0.2 => 16.0.2 
    style-loader: ^4.0.0 => 4.0.0 
    webpack: ^5.95.0 => 5.95.0 
    webpack-cli: ^5.1.4 => 5.1.4 

Thanks in advance!

alexander-akait commented 1 week ago

@adrienharnay sass doesn't know how to work with JSN files, so this behavior is logical, you need a custom resolver

That the // No need to pass loadPaths, because modern API handle them itself comment is not 100% right.

It works, but only for sass/scss

That without restrictions: [/.(((sa|sc|c)ss)|json)$/i],, the JSON file won't be picked up by the webpack resolver and thus it won't load.

It's expected because sass doesn't know how to parse JSON file

That we need to re-implement our importer logic in the sass-loader load function because it won't call our importer (?).

What do you mean?

Just use:

{
            loader: "sass-loader",
            options: {
              sourceMap: true,
              sassOptions: {
                loadPaths: [path.resolve(__dirname, "./src")],
                importer: [
                  SassJSONImporter({
                    includePaths: path.resolve(__dirname, "./src"),
                  })
                ],
              },
            },
},