material-ui icon indicating copy to clipboard operation
material-ui copied to clipboard

[docs] Next.js 13 transpilePackages and modularizeImports

Open mareson opened this issue 2 years ago • 5 comments

Duplicates

  • [X] I have searched the existing issues

Related page

https://mui.com/material-ui/guides/styled-engine/

Kind of issue

Missing information

Issue description

My project is a monorepository using Turborepo. I'm using Next.js 13 and would like to optimize the performance. I found an article where they use the new transpilePackages and modularizeImports properties to optimize the imports in the application (see here).

If I set up next.config.js according to the article. That is, I add @mui libraries to the transpilePackages parameter and then use the same parameters as in the article to modularizeImports:

{
    "@mui/material/?(((\\w*)?/?)*)": {
        transform: "@mui/material/{{ matches.[1] }}/{{member}}",
    },
    "@mui/icons-material/?(((\\w*)?/?)*)": {
        transform: "@mui/icons-material/{{ matches.[1] }}/{{member}}",
    },
}

I get a module not found error if I import css or styled from @mui/material:

https://nextjs.org/docs/messages/module-not-found
wait  - compiling /_error (client and server)...
error - ../../packages/core/icons/Icon.tsx:14:0
Module not found: Can't resolve '@mui/material/css'
import { css, styled } from "@mui/material";

I tried a lot of things and managed to get another similar bug, but with the alpha function (and some others as well). I assume the modularizeImports parameters are not correct, but I don't know how it should be correct.

Context 🔦

I found a page in the documentation regarding which I'm opening this issue, which still uses the next-transpile-modules package (replaced in just Next.js 13). I would be glad if this would also appear somewhere in the documentation and how to set it up properly. It would improve the performance of the application a lot.

mareson avatar Feb 16 '23 09:02 mareson

The css and styled are exported from @mui/material/styles, the imports @mui/material/css indeed does not exist. For the @mui/material-icons package it works nice, because each exported module has it's own folder. If you would like to use this feature for the @mui/material package as well, the config will need to be a bit more complex to cover these cases.

mnajdova avatar Feb 21 '23 13:02 mnajdova

We have the same issue with useTheme. Unfortunately NextJS's modularizeImports doesn't support a more complex config to account for this. (I know it's not really MUI's concern, but thought I'd leave this here to improve discoverability of the issue.)

omermizr avatar Feb 28 '23 12:02 omermizr

Hi, I am still getting the below error - Error: Module not found: Can't resolve 'C:\Users\SujoyDutta\Documents\GitHub\Next.js-FLoat-demo\float-demo\node_modules\next\dist\compiled@next\react-refresh-utils\loader.js'

Even though I used @mui/material/styles for the Theme provider

sujoydutta67 avatar Mar 01 '23 14:03 sujoydutta67

Hi, I am still getting the below error - Error: Module not found: Can't resolve 'C:\Users\SujoyDutta\Documents\GitHub\Next.js-FLoat-demo\float-demo\node_modules\next\dist\compiled@next\react-refresh-utils\loader.js'

Even though I used @mui/material/styles for the Theme provider

Are you using the treanspilePackages only for @mui/material-icons?

mnajdova avatar Mar 22 '23 11:03 mnajdova

We have the same issue with useTheme. Unfortunately NextJS's modularizeImports doesn't support a more complex config to account for this. (I know it's not really MUI's concern, but thought I'd leave this here to improve discoverability of the issue.)

There are workarounds, for example:

@/components/useTheme.ts:

  import { useTheme } from '@mui/material/styles';
  export default useTheme;

next.config.js:

  ...
  modularizeImports: {
    '@mui/material': {
      transform: '{{#if (eq member "useTheme")}}@/components/useTheme{{else}}@mui/material/{{member}}{{/if}}'
    '
  },
  ...

sarahvandomelen avatar May 02 '23 20:05 sarahvandomelen

At that point I would be fine with having a codemod that transforms all top level imports to 2nd level or default imports. Else it's just workarounds that can break easily when upgrading.

MJomaa avatar May 27 '23 11:05 MJomaa

Still having this issue X.x. not sure what the long term solution is here

pirtlj avatar Aug 15 '23 23:08 pirtlj

I found a workaround (spends almost a day just for this)

  modularizeImports: {
    '@mui/material/!(styles)/?*': {
      transform: '@mui/material/{{path}}/{{member}}',
      skipDefaultConversion: true,
    },
    '@mui/icons-material/?(((\\w*)?/?)*)': {
      transform: '@mui/icons-material/{{ matches.[1] }}/{{member}}',
    },
  },

works just fine for me

zourdyzou avatar Aug 16 '23 09:08 zourdyzou

I was scratching my head over this today when i started a new project and i get:

 Module not found: Can't resolve '@mui/material/useTheme'

robertwt7 avatar Sep 21 '23 07:09 robertwt7

I was scratching my head over this today when i started a new project and i get:

 Module not found: Can't resolve '@mui/material/useTheme'

Use import { useTheme } from '@mui/material/styles'; as well as createTheme, useTheme, ThemeProvider, styled, Theme, and alpha from @mui/material/styles.

nik0145 avatar Sep 27 '23 00:09 nik0145

It didn't work for me even after I changed the import @nik0145

The one that works was @zourdyzou solution because i modularized the import for performance previously

I found a workaround (spends almost a day just for this)

  modularizeImports: {
    '@mui/material/!(styles)/?*': {
      transform: '@mui/material/{{path}}/{{member}}',
      skipDefaultConversion: true,
    },
    '@mui/icons-material/?(((\\w*)?/?)*)': {
      transform: '@mui/icons-material/{{ matches.[1] }}/{{member}}',
    },
  },

works just fine for me

robertwt7 avatar Sep 27 '23 02:09 robertwt7

I think this problem is solved now, per https://github.com/mui/material-ui/issues/35450#issuecomment-1612276423.

oliviertassinari avatar Jan 18 '24 00:01 oliviertassinari