Next.js: SASS :export does not work with built-in SASS support throwing 'Selector ":export" is not pure'

Created on 3 Apr 2020  路  8Comments  路  Source: vercel/next.js

Bug report

Describe the bug

I use :export syntax to export variables from scss files and import them in JS. This worked great with next-sass, but does not even compile with the built-in SASS support.

To Reproduce

in Component.jsx:

import colors from './component.module.scss'

component.module.scss:

:export {
  white: #ffffff;
  black: #000000;
}

Expected behavior

colors in Component.jsx should be an object that looks something like this:

{
  white: "#ffffff",
  black: "#000000"
}

Actual behavior

It does not compile the scss file and throws:

ModuleBuildError: Module build failed (from ./node_modules/next/node_modules/css-loader/dist/cjs.js):
CssSyntaxError

(1:0) Selector ":export" is not pure (pure selectors must contain at least one local class or id)

System information

  • OS: Windows 10 (WSL)
  • Version of Next.js: 9.3.4
  • Version of SASS: 1.26.3

Additional information

next.config.js does not contain any code related to CSS or SASS

good first issue story

Most helpful comment

The issue is that the built-in css-loader options are using by default "pure" CSS modules.
I managed to work around this issue by updating this option for the specific css modules files that we use in our project (.module.scss):

/**
 * Stolen from https://stackoverflow.com/questions/10776600/testing-for-equality-of-regular-expressions
 */
const regexEqual = (x, y) => {
  return (
    x instanceof RegExp &&
    y instanceof RegExp &&
    x.source === y.source &&
    x.global === y.global &&
    x.ignoreCase === y.ignoreCase &&
    x.multiline === y.multiline
  );
};

module.exports = {
  webpack: config => {
    const oneOf = config.module.rules.find(
      rule => typeof rule.oneOf === 'object'
    );

    if (oneOf) {
      const moduleSassRule = oneOf.oneOf.find(rule =>
        regexEqual(rule.test, /\.module\.(scss|sass)$/)
      );

      if (moduleSassRule) {
        const cssLoader = moduleSassRule.use.find(({ loader }) =>
          loader.includes('css-loader')
        );
        if (cssLoader) {
          // Use the default CSS modules mode. Next.js use 'pure'. Not sure of all implications
          cssLoader.options.modules.mode = 'local';
        }
      }
    }

    return config;
  },
};

I'm not entirely sure of all the implications that this change might have...

All 8 comments

Any updates here? Known workaround?

I also have a need for this as well as the ability to add includePaths.

Hello Team
I have facing issues regarding the next-CSS . I have using next-CSS but they are giving me a warning and when I removed the next-CSS from next.config file. my style CSS has not loaded chunks in the production. and my CSS is out of order in a production build.
Can you plz help me.

I'm reporting the same problem as zorzysty in Next.js 9.3.6, with Sass 1.23.7. Is anybody looking into this?

The issue is that the built-in css-loader options are using by default "pure" CSS modules.
I managed to work around this issue by updating this option for the specific css modules files that we use in our project (.module.scss):

/**
 * Stolen from https://stackoverflow.com/questions/10776600/testing-for-equality-of-regular-expressions
 */
const regexEqual = (x, y) => {
  return (
    x instanceof RegExp &&
    y instanceof RegExp &&
    x.source === y.source &&
    x.global === y.global &&
    x.ignoreCase === y.ignoreCase &&
    x.multiline === y.multiline
  );
};

module.exports = {
  webpack: config => {
    const oneOf = config.module.rules.find(
      rule => typeof rule.oneOf === 'object'
    );

    if (oneOf) {
      const moduleSassRule = oneOf.oneOf.find(rule =>
        regexEqual(rule.test, /\.module\.(scss|sass)$/)
      );

      if (moduleSassRule) {
        const cssLoader = moduleSassRule.use.find(({ loader }) =>
          loader.includes('css-loader')
        );
        if (cssLoader) {
          // Use the default CSS modules mode. Next.js use 'pure'. Not sure of all implications
          cssLoader.options.modules.mode = 'local';
        }
      }
    }

    return config;
  },
};

I'm not entirely sure of all the implications that this change might have...

I am also looking for this functionality which is not working in Next.js. Please fix it!

Feel free to fix it @vavra7

Fixed in [email protected].

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kenji4569 picture kenji4569  路  3Comments

havefive picture havefive  路  3Comments

timneutkens picture timneutkens  路  3Comments

wagerfield picture wagerfield  路  3Comments

DvirSh picture DvirSh  路  3Comments