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

v14.2 causing build error for Material UI Icons #64518

Closed
lucasvieirasilva opened this issue Apr 15, 2024 · 24 comments · Fixed by #64558 or #64681
Closed

v14.2 causing build error for Material UI Icons #64518

lucasvieirasilva opened this issue Apr 15, 2024 · 24 comments · Fixed by #64558 or #64681
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. locked

Comments

@lucasvieirasilva
Copy link

lucasvieirasilva commented Apr 15, 2024

Link to the code that reproduces this issue

https://github.com/lucasvieirasilva/nextjs-mui-issue1

To Reproduce

  1. Clone the https://github.com/lucasvieirasilva/nextjs-mui-issue1 repo
  2. Install the dependencies npm install
  3. Run build npm run build

Current vs. Expected behavior

Currently, when there's any MUI Icon in the page the build command throws the following exception:

Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
    at nM (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:61599)
    at nM (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:61546)
    at nN (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64546)
    at nB (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:67538)
    at nD (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:66680)
    at nN (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64853)
    at nB (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:67538)
    at nD (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:66680)
    at nN (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64853)
    at nB (/Users/lucasvieira/Projects/mui-issue1/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:67538)
 ✓ Generating static pages (5/5)

> Export encountered errors on following paths:
        /page: /

I've also tested only the MUI component (e.g. Grid) and the build works correctly, it only fails with MUI Icons (@mui/icons-material)

If the static pages don't have any MUI Icon and any dynamic route page has MUI Icons the build works fine, but the page crashes when you try to access the application.

Provide environment information

Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 23.4.0: Fri Mar 15 00:11:05 PDT 2024; root:xnu-10063.101.17~1/RELEASE_X86_64
  Available memory (MB): 16384
  Available CPU cores: 12
Binaries:
  Node: 20.12.2
  npm: 10.5.0
  Yarn: 1.22.19
  pnpm: 8.6.12
Relevant Packages:
  next: 14.2.1-canary.5 // There is a newer canary version (14.3.0-canary.0) available, please upgrade! 
  eslint-config-next: 14.2.1
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.4.5
Next.js Config:
  output: standalone

Which area(s) are affected? (Select all that apply)

Not sure

Which stage(s) are affected? (Select all that apply)

next build (local)

Additional context

I've tested with the new v14.2.1-canary.5 version which is supposed to fix this issue, but apparently, it only fixes MUI components, not MUI icons.

Issue reference: #64369

I've tested with Next.js 14.1.4 and works fine.

The 14.2.1-canary.7 and 14.3.0-canary.0 versions are not working as well.

NEXT-3119

@lucasvieirasilva lucasvieirasilva added the bug Issue was opened via the bug report template. label Apr 15, 2024
@JonathanBrenner
Copy link

I'm having this issue as well!

@huozhi huozhi added the linear: next Confirmed issue that is tracked by the Next.js team. label Apr 15, 2024
@ElectricCodeGuy
Copy link

ElectricCodeGuy commented Apr 15, 2024

This should Not be closed... I have the Exact same issue using the newest version 14.2.1-canary.7

Running in Dev works fine but when I build and then next start i get:

Error: Minified React error #306; visit https://react.dev/errors/306?args[]=%5Bobject%20Object%5D&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

also using MUI Material and Icons. Everything worked fine before next 14.2

Bonus:

After the newest update I keep running out of memory too:

`> next build

▲ Next.js 14.2.1

  • Environments: .env.local

Creating an optimized production build ...
[webpack.cache.PackFileCacheStrategy] Caching failed for pack: Error: ENOSPC: no space left on device, write
uncaughtException [Error: ENOSPC: no space left on device, write] {
errno: -28,
code: 'ENOSPC',
syscall: 'write'
}`

Never seen this issue before... But it keeps happening. To fix it I delete the .next folder and then I can build again...

@filmic
Copy link

filmic commented Apr 16, 2024

          If anyone is facing this error, a fix I found for it is:

Change how you import material ui package from this:
import PieChartIcon from '@mui/icons-material/PieChart'

To this:
import { PieChart } from '@mui/icons-material'

Originally posted by @Tosinkoa in #63394 (comment)

@ibobo
Copy link

ibobo commented Apr 16, 2024

I'm having the same error on another package, "react-fast-marquee". The error happens during runtime if the page is marked with export const runtime="edge";, or during build as in @lucasvieirasilva case. It worked fine until 14.1.4.

It seems it's importing the package as {default: Component} instead of just the Component, but only in build/production. In dev mode all works fine.

I prepared a minimal reproduction codesandbox here

@lucasvieirasilva
Copy link
Author

@filmic thanks that works, however, for large projects this workaround might be very tedious to do since requires a big refactor.

@lucasvieirasilva
Copy link
Author

Found another related issue, in the layout.tsx, any MUI component inside the Layout component doesn't work.

Only works if changes from import Container from "@mui/material/Container" to import Container from "@mui/material/Container/Container or import { Container } from "@mui/material.

I think this has to do with @ibobo mentioned in this comment #64518 (comment)

@huozhi
Copy link
Member

huozhi commented Apr 16, 2024

I identify the issue is related to CJS dependency, preparing a fix in #64558 . If you're using @mui/icons-material I still recommend to use named import from the package such as

Prefer

import { Abc } from "@mui/icons-material"

rather than

import Abc from "@mui/icons-material/Abc"

The reason is that the direct subpath import @mui/icons-material/Abc.js is a CJS module, which will still have less benefit of treeshaking optimization

huozhi added a commit that referenced this issue Apr 16, 2024
## What

Determine if the client module is a CJS file and `default` export is
imported, then we include the whole module instead of using webpack
magic comments to only extract `default` export.

## Why

Unlike ESM, The `default` export of CJS module is not just `.default`
property, we need to include `__esModule` mark along with `default`
export to make it function properly with React client module proxy


Fixes #64518
Closes NEXT-3119
@Tosinkoa
Copy link

@filmic thanks that works, however, for large projects this workaround might be very tedious to do since requires a big refactor.

Yes, you're right. To avoid making it tedious, you can do ctrl + shift + f to do an overall search in your project, and search for @mui/icons-material/. To locate instance where you don't use curly braces for your import.
And you can also highlight what you want to change in a single file, and do ctrl + shift + h to make changes to multiple files with the same thing you've highlighted in one go.

And lastly for same file, you can do ctrl + h to edit multiple instance at once

@huozhi
Copy link
Member

huozhi commented Apr 16, 2024

Landed the fix on canary, please upgrade to v14.3.0-canary.5! 🙏

@justinh00k
Copy link
Contributor

Testing on 14.3.0-canary.5 I am still having the same issue. Changing all MUI imports, not just icons, was the only fix, (and this is bad practice for MUI). Any thing I need to do to allow importing default without this error?

@lucasvieirasilva
Copy link
Author

@justinh00k same

@ibobo
Copy link

ibobo commented Apr 17, 2024

Landed the fix on canary, please upgrade to v14.3.0-canary.5! 🙏

I confirm that my problem is fixed on 14.3.0-canary.5 (thanks!), but it seems @lucasvieirasilva's one is not.

@huozhi
Copy link
Member

huozhi commented Apr 17, 2024

@huozhi huozhi reopened this Apr 17, 2024
@huozhi
Copy link
Member

huozhi commented Apr 17, 2024

Taking another round of look for this case of material lib

@ElectricCodeGuy
Copy link

ElectricCodeGuy commented Apr 17, 2024

Found another related issue, in the layout.tsx, any MUI component inside the Layout component doesn't work.

Only works if changes from import Container from "@mui/material/Container" to import Container from "@mui/material/Container/Container or import { Container } from "@mui/material.

I think this has to do with @ibobo mentioned in this comment #64518 (comment)

This worked for me. Spend about 2 hours changing god knows how many imports, but it actually fixed the issue using 14.3.0-canary.5.

I also changed my Next/dynamic to React.Lazy witch solved an error using edge runtime, but I can see there is allready a pr for that.

ztanner pushed a commit that referenced this issue Apr 17, 2024
## What

Determine if the client module is a CJS file and `default` export is
imported, then we include the whole module instead of using webpack
magic comments to only extract `default` export.

## Why

Unlike ESM, The `default` export of CJS module is not just `.default`
property, we need to include `__esModule` mark along with `default`
export to make it function properly with React client module proxy


Fixes #64518
Closes NEXT-3119
huozhi added a commit that referenced this issue Apr 17, 2024
### Why

If you have a client entry that mixing `default` re-export and `*`
re-export, atm we cannot statically analyze all the exports from this
the boundary, unless we can apply barrel file optimization for every
import which could slow down speed.

```js
// index.js
'use client'
export * from './client'
export { default } from './client'
```

Before that happen we high recommend you don't mixing that and try to
add the client directive to the leaf level client module. We're not able
to determine what the identifiers are imported from the wildcard import
path. This would work if we resolved the actual file but currently we
can't.

### What

When we found the mixing client entry module like that, we treat it as a
CJS client module and include all the bundle in client like before what
we have the client components import optimization.

Ideally we could warn users don't apply the client directive to these
kinda of barrel file, and only apply them to where we needed.


Fixes #64518 
Closes NEXT-3119
@huozhi
Copy link
Member

huozhi commented Apr 17, 2024

I got a fix up in #64681 and landed, but there's still sth need to be changed on mui side to let users get better optimization of client code. This change is landed in 14.3.0-canary.9

The case of @mui/material/Container/index.js is a client boundary and with mixied exports, both export * and export { default }. we should remove the "use client" here since it's just a barrel file but hard to be optimized by default atm. there's already a "use client" directive in @mui/material/Container/Container.js, so we don't have to add another one in barrel file.

cc @oliviertassinari

@erik-lance
Copy link

Can confirm this issue was fixed on my end after updating from Next.js 14.2.1 to Next.js 14.2.2.

For reference, my issue was simply using a MUI element on my main page providing the same error as the initial issue.

@dschi
Copy link

dschi commented Apr 18, 2024

Next.js 14.2.2 works for me now, but I had to change one additional import:
import Grid from '@mui/material/Unstable_Grid2' -> import Grid from '@mui/material/Unstable_Grid2/Grid2'

@huozhi
Copy link
Member

huozhi commented Apr 18, 2024

To clarify about the fixes:

The mui icon related fix, which initially mentioned in the issue description, is fixed in 14.2.2.
The mui material subpath import issue, such as import Container from "@mui/material/Container", is fixed on canary 14.3.0-canary.9, not landed in stable patches yet.

@AbdullahElrubi
Copy link

Just tested it now and it is not working, still getting the same issue.
I don't like to change the imports of MUI components all over my app just for this.
image

@huozhi
Copy link
Member

huozhi commented Apr 18, 2024

@AbdullahElrubi can you provide a reproduction using next.js canary?

@MonstraG
Copy link
Contributor

MonstraG commented Apr 21, 2024

Latest canary fixed all of my issues without changing a single import path (all of my paths were default-style and 14.2.2 upgrade was not enough).

@AbdullahElrubi
Copy link

@huozhi the latest canary fixed the issue for me

huozhi added a commit that referenced this issue Apr 23, 2024
### Why

If you have a client entry that mixing `default` re-export and `*`
re-export, atm we cannot statically analyze all the exports from this
the boundary, unless we can apply barrel file optimization for every
import which could slow down speed.

```js
// index.js
'use client'
export * from './client'
export { default } from './client'
```

Before that happen we high recommend you don't mixing that and try to
add the client directive to the leaf level client module. We're not able
to determine what the identifiers are imported from the wildcard import
path. This would work if we resolved the actual file but currently we
can't.

### What

When we found the mixing client entry module like that, we treat it as a
CJS client module and include all the bundle in client like before what
we have the client components import optimization.

Ideally we could warn users don't apply the client directive to these
kinda of barrel file, and only apply them to where we needed.


Fixes #64518 
Closes NEXT-3119
Copy link
Contributor

github-actions bot commented May 9, 2024

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot added the locked label May 9, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 9, 2024
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. linear: next Confirmed issue that is tracked by the Next.js team. locked
Projects
None yet