vercel / next.js

The React Framework
https://nextjs.org
MIT License
123.23k stars 26.31k forks source link

CSS modules duplicated when used with `next/dynamic` #25456

Open mrmckeb opened 3 years ago

mrmckeb commented 3 years ago

What version of Next.js are you using?

10.2.2

What version of Node.js are you using?

14.16.0

What browser are you using?

Chrome

What operating system are you using?

macOS

How are you deploying your application?

Vercel

Describe the Bug

When using next/dynamic with CSS modules, we've found that CSS can be re-inserted (duplicated)

In our scenario, we have a simple <Text /> component that is already in use throughout the application. When we used <Text /> in a new component that was dynamically imported, styles for <Text /> were re-inserted.

These styles were inserted below all other styles, breaking some styles that rely on specificity - which is how we found this bug.

As a temporary workaround, we've removed that component from the dynamically loaded component.

Expected Behavior

Styles should not be re-inserted/duplicated.

To Reproduce

We haven't been able to reliably reproduce this in a standalone repo.

We've looked and found some potentially similar issues, and this might be related: https://github.com/vercel/next.js/issues/20203.

sgehrman commented 2 years ago

I'm getting duplicate css without using dynamic.

timneutkens commented 2 years ago

@sgehrman please provide a reproduction

bscaspar commented 2 years ago

I am encountering a similar issue - CSS modules are getting duplicated and overwritten for similar components on a page - e.g. implementations of a custom <Button /> component - after one of these components is dynamically loaded. No issue when the conditional dynamic component is not loaded. There's a clear flash of changing styles once the dynamic component is loaded.

Update: was initially on next@11.1.2, updating to v12.0.2 didn't fix this issue.

vborodulin commented 2 years ago

any updates on this issue?

vborodulin commented 2 years ago

still have issue

rikani commented 2 years ago

Next.js v12.1.0 still has problem.

Puvvl commented 2 years ago

Next.js 12.1.4 still has problem

ycfreeman commented 2 years ago

12.1.6 still has problem

PhilipeGatis commented 2 years ago

12.1.5 still has problem

NikooDev commented 2 years ago

12.1.6 still has problem :

Capture d’écran 2022-06-09 à 00 04 51
PepeBotella25 commented 2 years ago

Repo to reproduce this: https://github.com/PepeBotella25/css_module_dynamic_issue

Initially image

After adding dynamic component using the same "shared" component image

Since you need css chunks to reproduce it you have to do build+start

npm run build
npm run start

When second component get added its css brings the "shared" styles again affecting the cascade order: image

X7Becka commented 1 year ago

Yeah, 12.2.3 still no workaround

yakovlev-alexey commented 1 year ago

Experienced this issue in 12.3.1 and found a workaround.

TL;DR: add a hidden (display: none should work) div in App/Page. In this div render all the components that have their styles duplicated.


Explanation: webpack (or whatever) seems to check whether components used in a dynamic import are already present on the page. In my case everything was fine when a loadable component was imported on a specific page. Later I moved the component to _app.tsx and styles started to duplicate in the CSS file emitted for the loadable component.

Say you have a few components:

* uses means imports either directly or indirectly but without dynamic imports.

The issue may be reproduced in a few ways: 1) LoadableModal is used in App, Button is used in Page (sure, tested) 2) LoadableModal is used in Page, Button is used in App (not sure, need to test) 3) Button is used neither in Page nor in App. There is an additional LoadableForm component that uses Button used on the same page. (not sure, need to test)

When building Next.js checks imports to see whether components used in dynamic are already present on the page. Since the relation between Page and App is not direct there is no way for it to detect that the Button is already used.

My workaround was the following: add a hidden (display: none should work) div in App/Page. In this div render all the components that have their styles duplicated. With this fix in place Next.js should properly deduplicate styles.

Perhaps it is also possible to not render the component at all by using {false && <Button />}.

aloeugene commented 1 year ago

We're also experiencing this with Next@13.1.5.

image

And it's not reproducing running locally with next dev, which makes it even worse given the fact that we need to double-check such issues by building "prod" version locally OR just observing it when it gets to QA env (which uses "prod" version).

uaeio commented 1 year ago

It seems that this issue is connected with: https://github.com/vercel/next.js/issues/42082

Webbrother commented 1 year ago

The same issue without using dynamic. next@13.2.4

I'm wondering why this problem persists for a few years and a lot of tickets was closed without any solution.

potapovnikita commented 11 months ago

any solutions for this issue?

vasylkorchynskyi commented 11 months ago

Any updates here? Have the same issue with next@13.4.7

image
AustinCase commented 11 months ago

I am also having this issue with next@13.4.5 -- I am actively trying to work on reproduction, perhaps will lend itself to the issue.

My instinct is that it has to do with SSR and the bundling magic between layouts/pages...

roman-veryovkin commented 10 months ago

I have the same issue with next@13.4.17. Any workarounds so far?

AustinCase commented 10 months ago

I can actively reproduce it without dynamic.

Even if you have not visited both pages, if you have a Link component ( or something else that preloads the other page ). The server will stream down two css files, both with the EXCACT same selectors.

The browser for good reason can't dedup css selectors, instead it essentially does a merge. Ultimately I am just worried about the performance hit here, since it is doing the dedup on basically every shared component. Its also messy to read and a bad dev experience.

Hope this helps :)

ForsyteRun commented 9 months ago

Any solution?

monolithed commented 9 months ago

This bug is present even without using next/dynamic

Egor-Dubovik commented 8 months ago

I have the same issue in next@13.5.6 even without dynamic imports. Seriously this problem has been going on for so long and it still hasn't been fixed?

zachsitka commented 4 months ago

This is still an issue for me using next@14.1.3

EDIT: using dynamic imports

maiconsanson commented 4 months ago

It seems to be solved in 14.1.3 without dynamic imports (production only, dev still duplicating) for me.

https://github.com/vercel/next.js/pull/61198

ivangorbunoff commented 3 months ago

is there any solution? In large projects where components are often reused, duplicating styles greatly increases the final css file size. This is still an issue for me using next@14.1.4