NextJS 中 :global() css 模块选择器不纯的问题

问题描述 投票:0回答:4

因此,我正在将应用程序从 CRA 迁移到 NextJS,并且我遇到了某些组件和页面的 .module.scss 文件的错误:

Syntax error: Selector ":global(.label-primary)" is not pure (pure selectors must contain at least one local class or id)

我对所有 :global 和 :local css-module 选择器都收到此错误。根据我搜索的内容,我可以通过将选择器包装在类中并编辑 jsx 来解决此问题。但这岂不是违背了它的目的吗? 这在应用程序的 CRA 版本上而不是 NextJS 上如何工作?

编辑: 我对此的一个解决方案是将 :global() 选择器移动到在 _app.js 中导入的全局 css 文件,但我的问题是,我们有什么办法可以让这些样式像现在一样可用( :全局(...))?

css reactjs sass next.js css-modules
4个回答
4
投票

不,除了覆盖 webpack 配置本身之外,还没有任何解决方案。它在 CRA 中有效,因为他们可能有

mode
local
,而 Next.js 则有
pure


我还没有尝试覆盖

css-loader
webpack 配置,所以我只是建议一个解决方法。由于您使用的是 SCSS,因此您可以包装您的 pseudo-global [1] 样式,如下所示:

.root :global {
  .foo {
    color: red;
  }
}

现在将组件/页面包装在

div
中,并将该元素上的类设置为
styles.root
。然后,在所有子元素上您可以直接设置
className="foo"

import styles from "../styles/index.module.scss";

const IndexPage = () => (
  <div className={styles.root}>
    <div className="foo">This text should be red!</div>
  </div>
);

export default IndexPage;

请注意,使用此方法后您需要考虑有关特异性的问题,而且这不能直接用于动画,您需要将

keyframes
分开,然后将它们设为全局。

演示沙盒


[1]:此方法不会使样式真正全局化,因为样式仍然有作用域。仅当某些家长将

foo
作为课程时,
styles.root
课程才会起作用。仅当您不打算使用其他组件中的
:global(.selector)
,并且使用它们只是因为您想使用 JS 操作而不使用样式对象时,这才是更好的选择。

如果您希望它们真正是全局的,请在

styles.root
挂钩中将
document.documentElement
添加到
useEffect
,如下所示:

import { useEffect } from "react";
import styles from "../styles/index.module.scss";

const IndexPage = () => {
  useEffect(() => {
    document.documentElement.classList.add(styles.root);
    return () => {
      document.documentElement.classList.remove(styles.root);
    };
  }, []);

  return (
    <div className="foo">
      This text should be red, even if you put it in another component until the
      page is same. If you want it across pages inject it in _app or _document.
    </div>
  );
};

export default IndexPage;

演示沙盒

PS:在

html
_app
中向
_document
注入类与使用 全局样式表 完全相同,因为可能会发生多页面应用程序,然后只有组件的 CSS由于 Next.js 完成了自动 CSS 代码分割,因此将请求特定页面上的内容。如果情况并非如此,并且所有页面都共享相同的 CSS,那么无需将事情复杂化,只需使用
_app
中导入样式的常规方法即可。


3
投票

我也遇到了同样的问题,正确的写法是

.root:global {
   color:red
}

0
投票

另一种方法是制作一个容器,将其包裹起来,然后按如下方式进行:

import style from '../styles/style.module.css'
<div className={styles.container}>
    <p>Hello World</p>
</div>
.container p {
  font-size: 20px;
}

是的,如果您有很多标签和条件,您只需要在 CSS 文件中包含它们。


0
投票

如果您也在寻找使用 Nextjs v14+ 为 CSS 模块设置全局样式的解决方案(适用于 App-router 和 TurboPack)。

像这样在CSS文件中添加类

:global(.my__global__class) {
  color: violet;
}

在 JSX 中使用 classname="" 普通类名而不是 CSS-Module

// Wrong ❌ - Not-working

className={styles["my__global__class"]}

// Right ✅ Working

className="my__global__class"
© www.soinside.com 2019 - 2024. All rights reserved.