webpack-contrib / sass-loader

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

sass-loader doesn't work with :root declarations or css custom props #1027

Closed stratboy closed 2 years ago

stratboy commented 2 years ago

Bug report

I think sass-loader has troubles either with :root declarations or with css custom properties.

Actual Behavior

This can be seen here:

ERROR in ../scss/front-page.scss 1:0
Module parse failed: Unexpected token (1:0)
File was processed with these loaders:
 * ./node_modules/sass-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
> :root {
|   --border-radius: 7px;
| }

Expected Behavior

Should compile correctly since pure sass compilation of the same file does work prefectly. Both direct via shell, or via codekit app.

How Do We Reproduce?

front-page.scss does import _vars like this:@use "parts/_vars" as *; _vars does a lot of forwarding, sets some scss variables and mixins and the does the

:root{
  --border-radius: 7px;
}

Which seems to cause the issue when compiling.

On webpack config it's just a plain

      {
        test: /\.scss$/,
        use: {
          loader: "sass-loader"
        }
      }, 

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

System: OS: macOS 11.6 CPU: (4) x64 Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz Memory: 15.50 GB / 32.00 GB Binaries: Node: 14.16.1 - /usr/local/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 7.21.0 - /usr/local/bin/npm Browsers: Chrome: 98.0.4758.102 Firefox: 97.0 Safari: 15.0 Packages: babel-loader: ^8.2.3 => 8.2.3 browser-sync-webpack-plugin: ^2.3.0 => 2.3.0 file-loader: ^6.2.0 => 6.2.0 lodash-webpack-plugin: ^0.11.6 => 0.11.6 sass-loader: ^12.6.0 => 12.6.0 webpack: ^5.69.0 => 5.69.0 webpack-bundle-analyzer: ^4.5.0 => 4.5.0 webpack-cli: ^4.9.2 => 4.9.2

alexander-akait commented 2 years ago

You may need an additional loader to handle the result of these loaders.

You don't run sass-loader on this file, no problems with sass-loader or sass, check your configuration again

stratboy commented 2 years ago

This is my full current test configuration:

const path = require('path');
const webpack = require("webpack");
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');

module.exports = {
  mode: 'development',
  watch: true,

  entry: {
    shared: './src/shared.js',
    front_page: './src/front-page.js',
    front_page_style: '../scss/front-page.scss',
  },

  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
  },

  module: {
    rules: [
      {
        test: /swiper\.esm\.js|fancybox\.esm\.js/,
        sideEffects: false
      }, //tree shaking

      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            plugins: ['lodash'],
            presets: ['@babel/preset-env'],
            cacheDirectory: true
          }
        }
      }, // babel

      {
        test: /\.scss$/,
        use: {
          loader: "sass-loader"
        }
      }, 
    ] // rules
  }, // module

  optimization: {
    minimize: true,
    usedExports: true,
    providedExports: true,
    splitChunks: {
      cacheGroups: {
        visuals: {
          name: 'visuals',
          chunks: 'all',
          test: /[\\/]node_modules[\\/](swiper|@fancyapps\/ui|dom7|ssr-window|lazysizes|lr-js-modules\/offcanvas-slidemenu\.js|lr-js-modules\/validator.js|lodash)/
        },
      },
    }
  },

  plugins: [
    new BrowserSyncPlugin({
      port: 5759,
      proxy: {
        target: 'http://mysite.dev',
      },
    }),
  ],
};

At this point, I will probably use gulp for scss and browsersync standalone for watching..

alexander-akait commented 2 years ago

You need to setup css-loader and style-loader/mini-css-extract-plugin to convert CSS code to JS (i.e. to using import styles from "./style.scss")

alexander-akait commented 2 years ago

There are a lot of examples in our readme https://github.com/webpack-contrib/sass-loader#extracts-css-into-separate-files

stratboy commented 2 years ago

In fact, all I wanted with styles was just compile pure scss to pure css, I'm not using css in js so I don't need extraction, just compiling.

But anyway, I ended up thinking to use webpack for js only. Too complicated for me. Docs are not enough clear and easy to read. Articles outside often are not updated and show old syntax or plugins. A mess. Spent 2 weeks trying to figure out an optimal configuration to handle all the development tasks... And still trying... I give up, sorry. It's a pity, though.

I think it's time for a new and easier tool, since we devs always need more or less the same things, so we should be able to just tell directories (not files) and what to do with them (with js do this, with css do that), in plain english, no need to load plugins, softwares, loaders and the like, just list the tasks based on files and directories. But this is another discussion.

Thank you anyway, regards

alexander-akait commented 2 years ago

There are no easy tools, you will faced with the same using any bundler, compilation, transpiling and bundling are always not easy things. No directories in bundling, you have modules and each modules should be handled by something - babel/swc/sass/less/pure parsing.

I see you have front_page_style: '../scss/front-page.scss',, so just use it:

const path = require('path');
const webpack = require("webpack");
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');

module.exports = {
  mode: 'development',
  watch: true,

  entry: {
    shared: './src/shared.js',
    front_page: './src/front-page.js',
    front_page_style: '../scss/front-page.scss',
  },

  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
  },

  module: {
    rules: [
      {
        test: /swiper\.esm\.js|fancybox\.esm\.js/,
        sideEffects: false
      }, //tree shaking

      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            plugins: ['lodash'],
            presets: ['@babel/preset-env'],
            cacheDirectory: true
          }
        }
      }, // babel

      {
        test: /\.scss$/,
        use: [
          "css-loader",
          "sass-loader",
        ],
      }, 
    ] // rules
  }, // module

  optimization: {
    minimize: true,
    usedExports: true,
    providedExports: true,
    splitChunks: {
      cacheGroups: {
        visuals: {
          name: 'visuals',
          chunks: 'all',
          test: /[\\/]node_modules[\\/](swiper|@fancyapps\/ui|dom7|ssr-window|lazysizes|lr-js-modules\/offcanvas-slidemenu\.js|lr-js-modules\/validator.js|lodash)/
        },
      },
    }
  },

  plugins: [
    new BrowserSyncPlugin({
      port: 5759,
      proxy: {
        target: 'http://mysite.dev',
      },
    }),
  ],
};
alexander-akait commented 2 years ago

Also if you have shared code, better to use dependOn https://webpack.js.org/configuration/entry-context/#entry-descriptor, webpack doesn't know what can be shared between entrypoints, you can use multiple entrypoints and the same page and on different pages.

That's why I say that there is no easy way, and you will either have to understand the details, or unfortunately you will always have problems understanding how it works and how to set it up.

stratboy commented 2 years ago

Thank you very much, really, but answer to that code when I run webpack is

Can't resolve 'css-loader'

I already tried it, in fact. So I npm installed css-loader manually, then it didn't complain, but css seemed not to be compiled. I thought It was an output path issue, then added a path via loader options, but then started to complain with :root and like again. Sorry, too much for me :) Really, 2 weeks, I generally study carefully docs, and ask a lot in forums and the like, read tuts. I develop websites since 1999. I build custom wordpress themes, vue apps (with pre-defined auto-config webpack setups like vue cli, vite and the like), do something with Laravel. no problems with all those technologies. Thing is, probably webpack is not for me when it's time to fine grained configurations, I simply don't understand webpack's docs or webpack itself. But I'm not alone in this, though :) I just asked something to codekit app developer (which I used) and he answered that "he never used webpack because he enjoy his sanity"! Lol :D

I'm sure there are a lot of better developer out there than me and one is you. I simply prefer to go with another route.

Anyway, thank you very much, even for the dependOn suggestion, which I want to try for javascript of course.

alexander-akait commented 2 years ago

Can't resolve 'css-loader'

Sorry, it is not webpack problem, it means you don't install css-loader, run npm i css-loader.

already tried it, in fact. So I npm installed css-loader manually, then it didn't complain, but css seemed not to be compiled. I thought It was an output path issue, then added a path via loader options, but then started to complain with :root and like again. Sorry, too much for me :) Really, 2 weeks, I generally study carefully docs, and ask a lot in forums and the like, read tuts. I develop websites since 1999. I build custom wordpress themes, vue apps (with pre-defined auto-config webpack setups like vue cli, vite and the like), do something with Laravel. no problems with all those technologies. Thing is, probably webpack is not for me when it's time to fine grained configurations, I simply don't understand webpack's docs or webpack itself. But I'm not alone in this, though :) I just asked something to codekit app developer (which I used) and he answered that "he never used webpack because he enjoy his sanity"! Lol :D

Survivorship bias. If I come to PHP developers and ask how they feel about C#, I doubt that I hear any reasonable answer from the majority.

Really, 2 weeks, I generally study carefully docs, and ask a lot in forums and the like, read tuts.

We have https://github.com/webpack/webpack/discussions and you can always post your questions and problems. And there is nothing to worry about if you can’t understand something.

Also you can always provide link your repo (publicly or privately using for example twitter, you can found my link in my profile) and I will show how to setup what you need. Again bundling is not simple thing, you can compare it to C++/rust compilation, you really need to understand some of the details to understand how to set it up correctly.

stratboy commented 2 years ago

Thank you very much

kgrosvenor commented 2 years ago

I have the same issue, im using the following

import light from '!!style-loader?injectType=lazyStyleTag!sass-loader!../src/styles/lib.light.scss'

Then the error i get back is:

You may need an additional loader to handle the result of these loaders.
> :root {
|   --font-size: 16px;
|   --font-family: Helvetica, Courier, sans-serif;
    at handleParseError (C:\Users\kiera\Documents\Projects\design-kit\node_modules\webpack\lib\NormalModule.js:976:19)
    at C:\Users\kiera\Documents\Projects\design-kit\node_modules\webpack\lib\NormalModule.js:1095:5
"css-loader": "^6.7.1",
"sass": "^1.55.0",
"sass-loader": "^13.1.0",
"style-loader": "^3.3.1",

Importing the file normally works, was trying to get this working with multiple themes and pass them to a provider, im guessing it can't handle :root when importing with style-loader and this is the issue?