Next.js: 跨CSS块重复的样式会产生源订单问题

创建于 2020-04-30  ·  42评论  ·  资料来源: vercel/next.js

错误报告

描述错误

我有一个在多个页面上使用组件的应用程序。 当我构建项目时,该组件的样式在每个相关的CSS页面块中都是重复的; 这会产生视觉错误。

例如( some-componentinitial-page-component-override是应用于初始页面上DOM中相同元素的类):

initial-page.chunk.css

// component styles
.some-component { margin-bottom: 10px; }

// page specific override
.initial-page-component-override { margin-bottom: 20px; }

second-page.chunk.css

// component styles
.some-component { margin-bottom: 10px; }

当将second-page.chunk.css添加到DOM时,组件样式将重新应用到初始页面中定义的任何页面特定样式的顶部。 替代将丢失,并且错误的边距现在将应用于初始页面上的组件。 注意,这在开发模式下不是问题,仅在生产中。

重现

重现行为的步骤,请提供代码段或存储库:

  1. 结帐https://github.com/petewarman/nextjs-css-module-issue
  2. npm inpm run buildnpm start
  3. 将光标悬停在柠檬绿色按钮上
  4. 预加载第二页的样式表时,看到它变为粉红色

预期行为

样式声明不应在已编译的样式表中重复。 组件样式应该在页面特定样式之上加载(以它们自己的块吗?)。

系统信息

  • 作业系统:macOS
  • Next.js版本:9.3.6
  • Node.js版本:10.16.3
bug 3

最有用的评论

我遇到了完全相同的问题: https :

所有42条评论

我遇到了完全相同的问题: https :

这里也是同样的问题:cry:
我在这里描述了我的问题: https :

任何进展? 我仍然有同样的问题,无法投入生产。
已在9.3.7-canary.9

@爱德华多·佩德罗萨
状态:v9.3.7-canary.11,问题仍然存在。

我们的monorepo共享组件库中的组件似乎也存在类似的问题-应用程序中影响这些组件的任何样式都将被库样式覆盖,尽管事实是应用CSS文件中样式的特殊性较高,因此应该优先。 在开发模式下看起来不错,但不是生产:(

(我们将SCSS模块与@zeit/next-sass

image

image

当我使用@ zeit / next-sass或@ zeit / next-css时,顺序,首选项和块之间的重复项都很好。 :思维:

当我将nextjs更新到9.3并开始使用CSS模块时,真正的问题就开始了。

我尝试了两种方法(next-sass和内置方法)-在两种情况下都存在问题

我的堆栈:
1)CSS模块
2)SCSS
3)使用@use导入的Dart-Sass

尝试了很多变体,并且这个变体对我有用(没有样式重复):

1)package.json:

"@zeit/next-css": "^1.0.1",
"@zeit/next-sass": "^1.0.1",
"next": "9.2.1", (9.4.1 is current)
"node-sass": "npm:[email protected]", (this is dart sass, but can be used default)

2)next.config.js

const path = require('path')
const withSass = require('@zeit/next-sass')
const withCSS = require('@zeit/next-css')
const withBundleAnalyzer = require('@next/bundle-analyzer')({ // Optional, of course
  enabled: process.env.ANALYZE === 'true',
})

module.exports = withBundleAnalyzer(
  withCSS(
    withSass({
      cssModules: true,
      sassLoaderOptions: {
        // Resolving SASS absolute imports
        includePaths: [path.resolve(__dirname, 'src')],
      },
      cssLoaderOptions: {
        importLoaders: 2,
        localIdentName:
          process.env.NODE_ENV === 'production'
            ? '[hash:base64]'
            : '[name]__[local]__[hash:base64:5]',
      },
      webpack(config, options) {
        // Resolving absolute imports
        config.resolve.modules.push(path.join(__dirname, 'src'))

        // Make global styles work
        config.module.rules.forEach(rule => {
          if (rule.test && rule.test.toString().includes('.scss')) {
            rule.rules = rule.use.map(useRule => {
              if (typeof useRule === 'string') {
                return {
                  loader: useRule,
                }
              }

              if (useRule.loader.startsWith('css-loader')) {
                return {
                  oneOf: [
                    {
                      test: new RegExp('.module.scss$'),
                      loader: useRule.loader,
                      options: useRule.options,
                    },
                    {
                      loader: useRule.loader,
                      options: {},
                    },
                  ],
                }
              }
              return useRule
            })
            delete rule.use
          }
        })

        return config
      },
    }),
  ),
)

3)像这样导入全局(不是模块)样式:

index.scss:

...
<strong i="19">@import</strong> '~emoji-mart/css/emoji-mart.css';
...

如果有人尝试使用这种配置,那将是很好的,所以我可以确保这确实可行。

我建议替换为:

.other-page__component-override { background: pink; }

有了这个:

.other-page .component-override { background: pink; }

因此,特定于页面的样式仅适用于该特定页面=)。

我也有这个错误的麻烦。
我将next-css更改为内置CSS,但它发生了。
它可以在开发模式下工作,但是在使用CSR时不能在生产模式下工作。 在SSR中,没有问题。

我使用带有内置css支持的下一个9.4.4,我也遇到这个问题,它在生产中会发生。

下一个9.4.4中的相同问题。 仅在生产模式下

这将在下一个9.4.4的生产环境中发生,并且以某种方式我们找到了解决方案。

与使用node-sass ,我们尝试使用文档中的各种选项,并通过在next.config.js添加新的sassOptions来解决此问题。

module.exports = {
  ...,
  sassOptions: {
    outputStyle: 'expanded',
  },
}

参考: outputStyle

next build之后检查css classname之后,这似乎正在工作。
希望这可以帮助!

感谢您分享@ Howard86 ,尝试过,但是在这里没有用。 我们还在我们的构建中使用next-css和next-sass(不是next内置的CSS支持,并且在本期中描述了相同的问题),并且重复发生在来自纯css的类中,这些纯css作为css-导入模块,不是来自无礼的风格

@ Howard86 @ alexandre-marchina

我正在从下一个,下一个9.4.4开始使用内置CSS,您的解决方案也对我不起作用。 :哭:

我对antd和下一个最新的same有同样的问题

同样的问题。 CSS可以在开发人员中完美加载,但在产品中某些CSS片段无法加载

这里也是同样的问题。

下一个v9.5.1在prod构建上经历过相同的问题,在dev构建上经历过样式还可以。

此错误使在next.js中使用css-modules成为不可能(因为没有人愿意在样式中添加!important)

此错误使在next.js中使用css-modules成为不可能(因为没有人愿意在样式中添加!important)

您可以提高覆盖基本样式的样式的特异性。 例如,让我们将组件依赖项定义为Button <-IconButton <-MoreSpecificButton。 在这种情况下,Button拥有自己的样式,这些样式会在切换到另一页时重新加载,因此会覆盖IconButton和MoreSpecificButton中的样式。 如果IconButton的样式定义为.className.className ,而MoreSpecificButton的样式也定义为.className.className则Button不会覆盖它。 并且,在CSS中,IconButton和MoreSpecificButton样式的顺序是正确的,因此MoreSpecificButton的样式将始终覆盖IconButton-这是预期的。

下一个v9.5.1在prod构建上经历过相同的问题,在dev构建上经历过样式还可以。

我遇到了同样的问题。

尾风+1,引导程序。 当前的解决方法是通过_document.js中的rel rel导入所有样式。 对于Tailwind,它是自定义的CSS构建。 这个问题很烦人。

我正在顺时针使用css模块(正常的全局css导入)。 内联css解决了负载排序问题,但是我不知道它是否仍在重复,这只是一种解决方法。 在生产中,我没有注意到一种风格可以覆盖另一种风格。

https://github.com/vercel/next-plugins/issues/238#issuecomment -432211871

这已在最新的Next.js金丝雀上修复。 请升级到next@^9.5.3-canary.7 ,让我们知道!

例如,行高,字体粗细,背景颜色,边框在开发和生产中是不同的,因此对我来说不行。

@talaikis,请以完全可复制的演示打开一个新期刊! 我已经测试了此复制中给出的确切代码以及它现在在canary

修正给我,但它会引起另一个更严重的问题。
在我的情况下,当我仅使用Router.push( localhost:3000 /#change ) coming from localhost:3000`更改哈希URL时,所有样式表都会重新加载,从而导致屏幕闪烁。

你能试试9.5.3-canary.9吗?

@Timer运行npm i

image

我曾尝试9.5.3-canary.9但仍然无法解决散列问题。

我没有提到它,但是我使用的是9.5.2 ,当我迁移到9.5.3-canary.6时,当我使用路由器更改上述哈希值时,devtools控制台中也会出现错误。
该问题在9.5.3-canary.5不存在。

image

@fabinppk,请打开新版复制品!

只是想确认原始问题似乎已在9.5.3-canary.9修复。 谢谢@Timer

感谢您确认@petewarman!

@计时器确定。 我认为您的修复可以,并且与devtools中的此问题无关。
谢谢。 :+1:

可以使用9.5.6-canary.11确认这仍然在发生,类在块之间重复。

@glottonous在计时器中解决了在此问题中注释的所有问题。

附:我正在使用9.5.5。 👌👌

@fabinppk我可以确认直到9.5.6-canary.11仍在发生相同的问题。

@glottonous我对项目9.5.6-canary.11进行了一些测试,但没有任何问题。

如果您确实有问题,请通过参考此问题来打开一个新问题。 :+1:

在nextjs 10中,同样的问题

相同的问题10.0.1

我以可复制的演示开始了#19055。

此页面是否有帮助?
0 / 5 - 0 等级