问题 :global() css-module 选择器在 NextJS 中不是纯的
Issue with :global() css-module selectors not being pure in NextJS
所以我正在将一个应用程序从 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-模块选择器上都遇到了这个错误。根据我搜索的内容,我可以通过将选择器包装在 class 中并同时编辑 jsx 来解决此问题。但这不会破坏它的目的吗?
这在应用程序的 CRA 版本而不是 NextJS 上如何工作?
编辑:
我对此的一种解决方案是将 :global() 选择器移动到 _app.js 中导入的全局 css 文件,但我的问题是我们有什么办法可以使用这些样式就像他们现在一样 ( :global(...) )?
不,除了覆盖 webpack 配置本身之外,目前还没有任何解决方案。它在 CRA 工作,因为他们可能有 mode
: local
, while Next.js has pure
.
我还没有尝试覆盖 css-loader
webpack 配置,所以我只是建议一个解决方法。因为,你正在使用 SCSS,你可以像这样包装你的 pseudo-global [1] 样式:
.root :global {
.foo {
color: red;
}
}
现在将您的 component/page 包裹在 div
中,并在该元素上将 class 设置为 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]:此方法不会使样式真正成为全局样式,因为样式仍然在范围内。 class foo
仅在某些父级 styles.root
为 class 时才有效。仅当您不打算从其他组件使用 :global(.selector)
并且使用它们只是因为您想在没有样式对象的情况下使用 JS 操作 class 名称时,这是更可取的。
如果您希望它们真正成为全球性的,请在 useEffect
挂钩中将 styles.root
添加到 document.documentElement
,如下所示:
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:在_app
或_document
中将class注入html
与不完全相同使用 global stylesheet,因为您可能有多页应用程序,那么只有特定页面上的组件的 CSS 会被请求,因为已完成自动 CSS 代码拆分通过 Next.js。如果情况并非如此,并且您的所有页面都共享相同的 CSS,则无需将事情复杂化,只需使用在 _app
.
中导入样式的常规方法即可
所以我正在将一个应用程序从 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-模块选择器上都遇到了这个错误。根据我搜索的内容,我可以通过将选择器包装在 class 中并同时编辑 jsx 来解决此问题。但这不会破坏它的目的吗? 这在应用程序的 CRA 版本而不是 NextJS 上如何工作?
编辑: 我对此的一种解决方案是将 :global() 选择器移动到 _app.js 中导入的全局 css 文件,但我的问题是我们有什么办法可以使用这些样式就像他们现在一样 ( :global(...) )?
不,除了覆盖 webpack 配置本身之外,目前还没有任何解决方案。它在 CRA 工作,因为他们可能有 mode
: local
, while Next.js has pure
.
我还没有尝试覆盖 css-loader
webpack 配置,所以我只是建议一个解决方法。因为,你正在使用 SCSS,你可以像这样包装你的 pseudo-global [1] 样式:
.root :global {
.foo {
color: red;
}
}
现在将您的 component/page 包裹在 div
中,并在该元素上将 class 设置为 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]:此方法不会使样式真正成为全局样式,因为样式仍然在范围内。 class foo
仅在某些父级 styles.root
为 class 时才有效。仅当您不打算从其他组件使用 :global(.selector)
并且使用它们只是因为您想在没有样式对象的情况下使用 JS 操作 class 名称时,这是更可取的。
如果您希望它们真正成为全球性的,请在 useEffect
挂钩中将 styles.root
添加到 document.documentElement
,如下所示:
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:在_app
或_document
中将class注入html
与不完全相同使用 global stylesheet,因为您可能有多页应用程序,那么只有特定页面上的组件的 CSS 会被请求,因为已完成自动 CSS 代码拆分通过 Next.js。如果情况并非如此,并且您的所有页面都共享相同的 CSS,则无需将事情复杂化,只需使用在 _app
.