:global() css-module 选择器在 NextJS 中不是纯的问题 [英] Issue with :global() css-module selectors not being pure in NextJS

查看:150
本文介绍了:global() css-module 选择器在 NextJS 中不是纯的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在将一个应用程序从 CRA 迁移到 NextJS,我遇到了一些组件和页面的 .module.scss 文件的错误:

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:

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 上是如何工作的?

I get this error for all the :global and :local css-module selectors. Based on what I have searched I can fix this issue by wrapping the selector in a class and editing the jsx aswell. but wouldn't that defeat it's purpose? And how is this working on the CRA version of the app and not on NextJS?

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

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(...) )?

推荐答案

除了覆盖 webpack 配置本身之外,目前还没有任何解决方案.它在 CRA 工作,因为他们可能有 mode:local,而 Next.js 有 pure.

No there isn't any solution as of yet other than overriding the webpack config itself. It was working in CRA because they probably have mode: local, while Next.js has pure.

我没有尝试覆盖 css-loader webpack 配置,所以我只是建议一种解决方法.由于您使用的是 SCSS,您可以像这样包装您的 pseudo-global [1] 样式:

I haven't tried overriding css-loader webpack config, so I am simply suggesting a workaround. Since, you are using SCSS, you can wrap your pseudo-global [1] styles like this:

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

现在将您的组件/页面包装在 div 中,并在该元素上将类设置为 styles.root.然后,在所有子元素上,您可以直接设置 className="foo".

Now wrap your component/page in a div and set the class as styles.root on that element. Then, on all the child elements you can directly set 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分开,然后将它们全局化.

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.

演示沙盒

[1]:此方法不会使样式真正全局化,因为样式仍然是作用域的.foo 类仅在某些父级将 styles.root 作为类时才起作用.仅当您不打算从其他组件中使用 :global(.selector) 并且只是因为您想使用不带样式对象的 JS 来操作类名时才使用它们,这才是可取的.

[1]: This method doesn't make the styles truly global as the styles are still scoped. The class foo will work only when some parent has styles.root as class. 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.

如果您希望这些是真正全局的,请将 styles.root 添加到 document.documentElement 中的 useEffect 挂钩中,如下所示:

If you want these to be truly global, add styles.root to document.documentElement in an useEffect hook like this:

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 中向 html 注入类与使用 全局样式表,因为它可能如果您有多页应用程序,那么由于 Next.js 会自动进行 CSS 代码拆分,因此只会请求特定页面上组件的 CSS.如果不是这种情况,并且所有页面共享相同的 CSS,则无需复杂化,只需在 _app 中导入样式的常规方法即可.

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. 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.

这篇关于:global() css-module 选择器在 NextJS 中不是纯的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆