因此,我正在将应用程序从 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 文件,但我的问题是,我们有什么办法可以让这些样式像现在一样可用( :全局(...))?
不,除了覆盖 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
中导入样式的常规方法即可。
我也遇到了同样的问题,正确的写法是
.root:global {
color:red
}
另一种方法是制作一个容器,将其包裹起来,然后按如下方式进行:
import style from '../styles/style.module.css'
<div className={styles.container}>
<p>Hello World</p>
</div>
.container p {
font-size: 20px;
}
是的,如果您有很多标签和条件,您只需要在 CSS 文件中包含它们。
如果您也在寻找使用 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"