Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Importing a component in both _app.js and a page duplicates component css #20203

Closed
guilhermehn opened this issue Dec 15, 2020 · 17 comments
Closed
Labels
bug Issue was opened via the bug report template.

Comments

@guilhermehn
Copy link

Bug report

Describe the bug

A component css is duplicated when imported by both _app.js and any page.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Create a component with a css module
  2. Import and use it in _app.js
  3. Import and use it in any page
  4. Import a css module in _app.js
  5. npm ci && npm run build && npm start

Repository: https://github.com/guilhermehn/next-duplicate-css-repro

Live example: https://next-duplicate-css-repro.vercel.app/

Expected behavior

The component css should not be duplicated.

Screenshots

image

System information

  • OS: Linux
  • Version of Next.js: 10.0.3
  • Version of Node.js: 14.15.1
  • Deployment: next start, Vercel

Additional context

@guilhermehn guilhermehn added the bug Issue was opened via the bug report template. label Dec 15, 2020
@vietanh74
Copy link

Same issue. This is preventing me from using next for future projects. Could you please advise when this will be fixed?

@iksent
Copy link

iksent commented Jan 25, 2021

Why Next team ignores such a big problem? This is just unreal to use Next with this bug.
Personally I am experiencing problems with styles for more than year since this issue.

Very disappointing, because of Next has no competitors now.

@badsyntax
Copy link

I'm not incredibly experienced with next but I feel like the example posted by OP is abusing the purpose of _app.js.
Can you solve this by taking a different approach? Instead of rendering common components in _app.js, compose your pages using a Page component or similar, and stick common components in there. I don't see how this approach is a blocker to anyone, but I could be missing something.

@iksent
Copy link

iksent commented Jan 25, 2021

My situation:

  1. CSS Modules
    For example I have basic components "Row" and "Button".

  2. Common layout for pages
    Inside the _app.tsx I have Layout Component, that contains Header and Footer.
    Header contains Row and Buttons - This is where the problems begin: Take a look at issue's title "Importing a component in both _app.js and a page duplicates component css"

I don't think, that using common layout component inside each page is a good idea, because it will be recreated at each page.
So header and footer will be destroyed and created again at each page navigation.

@badsyntax
Copy link

The approach I mentioned is a standard approach, as shown in the official examples.

Example page with common Layout component: https://github.com/vercel/next.js/blob/f06c58911515d980e25c33874c5f18ade5ac99df/examples/blog-starter/pages/index.js

Here's the Layout component: https://github.com/vercel/next.js/blob/f06c58911515d980e25c33874c5f18ade5ac99df/examples/blog-starter/components/layout.js

I highly doubt there's any significant perf issues here. There'll certainly be no dom thrashing as React is doing it's vdom diffing, and it really doesn't take much to re-render the common components on page navigation.

@badsyntax
Copy link

To clarify, while this still could be a bug, i'm just proposing a workaround.

@alexandre-marchina
Copy link

I'm not incredibly experienced with next but I feel like the example posted by OP is abusing the purpose of _app.js.
Can you solve this by taking a different approach? Instead of rendering common components in _app.js, compose your pages using a Page component or similar, and stick common components in there. I don't see how this approach is a blocker to anyone, but I could be missing something.

It's not abusing in any way, since this is something documented in the section about "Custom App" in the official docs
https://nextjs.org/docs/advanced-features/custom-app

Persisting layout between page changes

And there is an example with a Layout component applied in _app.js as well
https://github.com/vercel/next.js/blob/canary/examples/with-app-layout/pages/_app.js

@badsyntax
Copy link

Thanks, I agree, based on the docs it's not an abuse. This is a straight-up bug. I don't see any problems with the workaround though. Btw I don't have a strong opinion about this, just trying to help folks out.

@alexandre-marchina
Copy link

alexandre-marchina commented Jan 25, 2021

Maybe could be a workaround, but in our case here we've already had an abstraction for a Layout component implemented inside _app.js applied in several projects. We have stared to experience this behavior in a transition from the legacy next-css and next-sass plugins to the official built-in CSS support

@edgardz
Copy link

edgardz commented Feb 1, 2021

My workaround, for now, is to just import my Layout component on each page.
I left it being rendered on _app.js as I always did, just added an import on each page in order to trick the compiler.
I hope they fix this soon.

@iksent
Copy link

iksent commented Mar 15, 2021

@ijjk @timneutkens @Timer, is anybody home? :)

@Hellaeh
Copy link

Hellaeh commented Mar 29, 2021

While, we're all waiting for official fix. Did someone found temporary solution ?
I've tried fiddling with next.config.js and css-loader to add prefixes to all classnames, loaded from _app (directly or not), but it didn't work as expected (i believe it was a right direction, but wrong approach).
As far as i understand, the problem is not trivial. For example, just deleting duplicate classes in .css output files in .next directory, leads to broken styles elsewhere.

@ListeH
Copy link

ListeH commented May 4, 2021

Guys, solution for me:

  • npm i optimize-css-assets-webpack-plugin
  • add to next.config.js to webpack part this code:
if (Array.isArray(config.optimization.minimizer)) {
    config.optimization.minimizer.push(new OptimizeCSSAssetsPlugin({}))
}

config.plugins.push(
    new options.webpack.optimize.LimitChunkCountPlugin({
        maxChunks: 1,
    }),
)
  • options is second parameter of webpack
    webpack: (config, options) => {

@dread-44
Copy link

dread-44 commented Jun 12, 2021

@ListeH 's solution cleaned up my styles, but unfortunately they're still in the wrong order.

Edit: My project was appending another set of styles in <head> x_x

@sokra
Copy link
Member

sokra commented Jun 21, 2021

This might be fixed by webpack 5 / next.js 11, due to the use of dependOn for _app and pages.

@guilhermehn
Copy link
Author

@sokra It's fixed by next@11! I've updated the live example. Thank you!

image

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests