选择器“:root”不是纯选择器(纯选择器必须包含至少一个本地类或 id)-带有 SASS 模块的 NextJS

yoy*_*oyo 10 css sass css-modules react-css-modules next.js

我最近开始在 next.js 项目中使用模块,但在新创建的 .module.scss 文件中不断收到此错误:“Selector ":root" is not pure(纯选择器必须包含至少一个本地选择器)类或 ID)”。我知道这是因为我没有使用纯 css 选择器,就像我在网上其他地方看到的那样,唯一的问题是我正在使用的导入,但我需要这些变量的导入,如$cl-light-gray下面的示例文件所示:

@import "src/common/styles/global-styles.scss";
@import "node_modules/bootstrap/scss/bootstrap";
@import "src/common/styles/palette.scss";
@import "src/common/styles/typography.scss";

.dashboard-dropdown-hover {
  @extend .px-1;
  @extend .py-2;
  @extend .mt-3;
  border: 1px solid transparent;
  border-radius: 8px;
  transition: 200ms;
  background-color: transparent;
}
.dashboard-dropdown-hover:hover {
  background-color: $cl-light-gray;
}

Run Code Online (Sandbox Code Playgroud)

有谁能解决我应该如何解决这个导入问题?我知道如果我切换回 .scss 它将起作用,但我试图避免导入 _app.tsx 中的所有 .scss 文件,因为这将至少有 30 个导入,而且这些样式并不打算是全局的。最后,当我使用 Sass 时,为什么 Next.js 期望我使用纯 css 选择器,而使用 Sass 是因为它的非纯元素?

yoy*_*oyo 6

在互联网上搜索了几个小时后,我从这里找到了一个很好的解决方案: https: //dhanrajsp.me/snippets/customize-css-loader-options-in-nextjs

编辑:如果您使用的是 Next.js 12,请检查上面文章的底部,因为解决方案有点不同。

您需要更改 next.config.js 文件以包含以下内容:

/** @type {import('next').NextConfig} */
require("dotenv").config();
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
  );
};
// Overrides for css-loader plugin
function cssLoaderOptions(modules) {
  const { getLocalIdent, ...others } = modules; // Need to delete getLocalIdent else localIdentName doesn't work
  return {
    ...others,
    localIdentName: "[hash:base64:6]",
    exportLocalsConvention: "camelCaseOnly",
    mode: "local",
  };
}
module.exports = {
  webpack: (config) => {
    const oneOf = config.module.rules.find(
      (rule) => typeof rule.oneOf === "object"
    );
    if (oneOf) {
      // Find the module which targets *.scss|*.sass files
      const moduleSassRule = oneOf.oneOf.find((rule) =>
        regexEqual(rule.test, /\.module\.(scss|sass)$/)
      );

      if (moduleSassRule) {
        // Get the config object for css-loader plugin
        const cssLoader = moduleSassRule.use.find(({ loader }) =>
          loader.includes("css-loader")
        );
        if (cssLoader) {
          cssLoader.options = {
            ...cssLoader.options,
            modules: cssLoaderOptions(cssLoader.options.modules),
          };
        }
      }
    }
    return config;
  },
};

Run Code Online (Sandbox Code Playgroud)

我对 webpack 不太熟悉,也不知道它到底是如何工作的,但这个解决方案对我有用。如果需要,您还可以通过执行 (scss|sass|css) 更改正则表达式以包含 css。