[vercel/next.js]使用 next/动态导入时 CSS 模块有时不会加载

2024-05-10 845 views
6
运行next info(从版本 12.0.8 及更高版本可用)
Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 20.3.0: Thu Jan 21 00:06:51 PST 2021; root:xnu-7195.81.3~1/RELEASE_ARM64_T8101
Binaries:
  Node: 14.17.0
  npm: 6.14.13
  Yarn: 1.22.10
  pnpm: N/A
Relevant packages:
  next: 12.0.8
  react: 17.0.2
  react-dom: 17.0.2
您使用的 Next.js 版本是什么?

12.0.8

您使用的 Node.js 版本是什么?

14.17

描述错误

使用 加载组件时next/dynamic,CSS 模块有时无法正确加载。这看起来可能类似于https://github.com/vercel/next.js/issues/18252,它被描述为已修复(尽管没有链接的 PR 显示修复)。

此错误仅在运行next build+时发生next start。在开发中按预期工作 ( next dev)。此外,它发生的情况似乎非常具体,我试图在重现步骤中尽可能清晰、简洁地概述这些情况。

预期行为

CSS 模块应加载到文档中,以便应用您的样式。

重现 Repro 存储库和部署

create-next-app --typescript我使用12.0.8创建了一个演示: https://github.com/jzxhuang/dynamic-import-css-module-next-bug

它托管在: https: //dynamic-import-css-module-next-bug.vercel.app/

隔离繁殖步骤
  1. 直接转到https://dynamic-import-css-module-next-bug.vercel.app/broken/one ,注意按钮有红色背景
  2. 单击链接到/foo.该按钮现在将具有清晰的背景,即使它是完全相同的组件,没有任何更改。

这可以通过 SCSS 和 CSS 模块来重现。使用https://dynamic-import-css-module-next-bug.vercel.app/broken/two重复上述步骤将破坏蓝色按钮。这在“生产”版本中重现,如果您遵循与 相同的步骤next dev,则 上的按钮/foo应始终为正确的颜色。

它有效的情况,但为什么呢?

上述步骤是我们在生产中发现的此错误的独立再现。现在,事情开始变得非常奇怪,我们决定做一些更多的实验。我不确定以下场景是否会有帮助,或者只是让您陷入白费力气,但我们开始吧:

  1. 转到https://dynamic-import-css-module-next-bug.vercel.app
  2. 点击链接/broken/one,请勿刷新
  3. 单击链接到/foo.
  4. 预计按钮现在是红色的......

我们还在 paths 下创建了一些其他示例/working/*。这里唯一的区别是我们加载 2、3 或 0 个按钮。由于某种原因,这些似乎工作正常,但如果您只加载一个broken/one按钮(如和中所示) broken/two,样式就会被破坏。

如果你不延迟加载,一切都很好

回到有意义的事情。该示例/working/three表明蓝色按钮始终是正确的颜色。它不是在 /foo 中动态导入的,因此不存在与动态导入的按钮相同的错误。

DOM 中发生了什么?

在 /broken/one 上,我们看到按钮具有comp-one_button__MtA0_样式表中的类0ff09bacf4af1553.css图像

当我们点击进入时/foo,按钮仍然具有相同的类,但样式表没有被应用。 图像

我不确定这可能的根本原因是什么,但在动态导入时不知何故缺少样式表,并且它似乎与在动态导入的组件内使用一个组件上的组件有关。

回答

2

嘿,想知道这方面是否有任何见解或线索!它影响了我们的生产,并且我们没有任何已知的解决方法 - 需要 next/dynamic 以避免出现与 SSR 不兼容的有问题的库导入。谢谢!

0

遇到类似的缺少 css 文件的问题!

0

碰撞,nextjs 12.1.5 上有同样的问题

3

在 NextJS 12.2.2 上也看到了这一点。可以确认如果不使用动态导入,问题就会消失。

3

#17464 中提到的修复作为临时解决方法对我有用:

// In _app.tsx
const router = useRouter();

useEffect(() => {
  const handleRouteChange = () => {
    const styleElements = document.querySelectorAll('style[media="x"]');
    styleElements.forEach(styleTag => {
      styleTag.removeAttribute('media');
    });
  };

  router.events.on('routeChangeComplete', handleRouteChange);
  router.events.on('routeChangeStart', handleRouteChange);
}, [router]);
9

这个问题在接下来的12.2.4上仍然存在,并且已经不是很长一段时间了,突然出现了。

5

NextJS 13 的 AppDir beta 版本中也出现此问题。

2

现在使用 NextJS 13 遇到同样的问题。这里有什么消息吗?

4

Next.js 13 也存在同样的问题,当从主页导航到任何其他页面时,CSS 不起作用。

3

到目前为止有任何线索,或者有任何解决方法吗?看来它只发生在我部署后的生产中。

6

就我而言,我使用来自 CMS 的数据构建一个网站。所以我想使用 Next/dynamic 将所需的组件加载到当前活动的站点。

我尝试了各种方法,但最终通过开关解决了问题。我想我们必须等待未来的版本才能通过动态修复问题。目前我只建议将它与不加载额外 CSS 的小组件一起使用。

下面是我是如何做到的,就像这样,组件将以正常方式返回,并且 CSS 模块将被加载:

          `{components.map((component: any, k: any) => {
              if (componentsProps[k].componentregion === regionNum) {

                switch (component) {
                  case "Example_component1":
                    return (
                      <Example_component1
                        componenttype={componentsProps[k].componenttype}
                        componentid={componentsProps[k].componentid}
                        key={k}
                      />
                    )
                  break;
                  case "Example_component2":
                    return (
                      <Example_component2
                        componenttype={componentsProps[k].componenttype}
                        componentid={componentsProps[k].componentid}
                        key={k}
                      />
                    )
                  break;
                  case "Example_component3":
                    return (
                      <Example_component3
                        componenttype={componentsProps[k].componenttype}
                        componentid={componentsProps[k].componentid}
                        key={k}
                      />
                    )
                  break;
                  case "Example_component4":
                    return (
                      <Example_component4
                        componenttype={componentsProps[k].componenttype}
                        componentid={componentsProps[k].componentid}
                        key={k}
                      />
                    )
                  break;
                }
              }
            })}`
7

同样的问题在这里:( v.13.4.3

8

13.4.4中同样的问题

0

next.js 13.4.7 存在同样的问题

4

此问题的一种可能的解决方法是将所有异步块移至一组。

next.config.mjs:

export default {
  webpack(config, context) {
    const { isServer, dev } = context
    if(!isServer && !dev) {
       config.optimization.splitChunks.cacheGroups.asyncChunks = {
         enforce: true,
         type: "css/mini-extract",
         chunks: 'async',
       }
    }
   return config
  }
}
1

这里有同样的问题 next.js v 13.4.19