简体   繁体   English

:global() css-module 选择器在 NextJS 中不是纯的问题

[英]Issue with :global() css-module selectors not being pure in NextJS

So I'm migrating an app from CRA to NextJS and I have encountered an error for the .module.scss files of some components and pages:所以我正在将一个应用程序从 CRA 迁移到 NextJS,我遇到了一些组件和页面的 .module.scss 文件的错误:

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

I get this error for all the :global and :local css-module selectors.对于所有 :global 和 :local css-module 选择器,我都会收到此错误。 Based on what I have searched I can fix this issue by wrapping the selector in a class and editing the jsx aswell.根据我的搜索,我可以通过将选择器包装在一个类中并编辑 jsx 来解决这个问题。 but wouldn't that defeat it's purpose?但这不会破坏它的目的吗? And how is this working on the CRA version of the app and not on NextJS?这在应用程序的 CRA 版本而不是 NextJS 上是如何工作的?

EDIT: One solution I have for this is moving :global() selectors to the global css files that are imported in _app.js but my question is that is there any way that we can have so these styles would be usable like they are right now ( :global(...) )?编辑:我为此提供的一种解决方案是将 :global() 选择器移动到在 _app.js 中导入的全局 css 文件,但我的问题是我们有什么办法可以使这些样式像正确的一样可用现在( :global(...) )?

No there isn't any solution as of yet other than overriding the webpack config itself.不,除了覆盖 webpack 配置本身之外,还没有任何解决方案。 It was working in CRA because they probably have mode : local , while Next.js has pure .它在 CRA 中工作,因为他们可能有mode : local ,而 Next.js 有pure


I haven't tried overriding css-loader webpack config, so I am simply suggesting a workaround.我没有尝试覆盖css-loader webpack 配置,所以我只是建议一个解决方法。 Since, you are using SCSS, you can wrap your pseudo-global [1] styles like this:由于您使用的是 SCSS,因此您可以像这样包装伪全局[1]样式:

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

Now wrap your component/page in a div and set the class as styles.root on that element.现在将您的组件/页面包装在一个div中,并将该类设置为该元素上的styles.root Then, on all the child elements you can directly set className="foo" .然后,在所有子元素上,您可以直接设置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;

Note that, you need to consider issues regarding specificity after this method, also this doesn't directly work with animations, you need to separate the keyframes and then make them global.请注意,您需要在此方法之后考虑有关特异性的问题,这也不能直接用于动画,您需要将keyframes分开,然后将它们设为全局。

Demo Sandbox演示沙盒


[1]: This method doesn't make the styles truly global as the styles are still scoped. [1]:此方法不会使样式真正全局化,因为样式仍然是作用域的。 The class foo will work only when some parent has styles.root as class.foo仅在某些父级将styles.root作为类时才起作用。 This is preferrable only if you didn't intend to use your :global(.selector) from other components, and were using them just because you wanted to manipulate the class names using JS without the styles object.仅当您不打算从其他组件中使用:global(.selector)并且只是因为您想使用没有样式对象的 JS 来操作类名时才使用它们,这才是可取的。

If you want these to be truly global, add styles.root to document.documentElement in an useEffect hook like this:如果您希望这些是真正全局的,请在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;

Demo Sandbox演示沙盒

PS: Injecting class to html in _app or _document is not exactly same as using a global stylesheet , as it may happen that you have multi-page application, then only the CSS of the components on a particular page will be requested because of automatic CSS code-splitting done by Next.js. PS:在_app_document class 注入html与使用全局样式表并不完全相同,因为您可能有多页应用程序,那么由于自动 CSS,将仅请求特定页面上组件的 CSS Next.js 完成的代码拆分。 If that's not the case and all your pages share same CSS, then there is no need to complicate things, just go with the conventional method of importing styles in _app .如果不是这种情况,并且所有页面共享相同的 CSS,则无需复杂化,只需使用在_app中导入样式的常规方法即可。

I had the same problem, the right writing is我有同样的问题,正确的写作是

.root:global {
   color:red
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM