TheProgrammer
TheProgrammer

Reputation: 1489

How to properly configure babel for material-ui in Next.js?

DOCS:

https://material-ui.com/guides/minimizing-bundle-size/#development-environment

"Create a .babelrc.js file in the root directory of your project:

const plugins = [
  [
    'babel-plugin-transform-imports',
    {
      '@material-ui/core': {
        // Use "transform: '@material-ui/core/${member}'," if your bundler does not support ES modules
        'transform': '@material-ui/core/esm/${member}',
        'preventFullImport': true
      },
      '@material-ui/icons': {
        // Use "transform: '@material-ui/icons/${member}'," if your bundler does not support ES modules
        'transform': '@material-ui/icons/esm/${member}',
        'preventFullImport': true
      }
    }
  ]
];

module.exports = {plugins};"

https://nextjs.org/docs/advanced-features/customizing-babel-config

"To add presets/plugins with custom configuration, do it on the next/babel preset like so:

{
  "presets": [
    [
      "next/babel",
      {
        "preset-env": {},
        "transform-runtime": {},
        "styled-jsx": {},
        "class-properties": {}
      }
    ]
  ],
  "plugins": []
}"

QUESTION:

How to properly configure babel for material-ui in Next.js ? My implementation below is apparently incorrect as import { ConstructionOutlined } from '@material-ui/icons';is still causing very long load times in dev mode. I observed no error messages when trying the below implementation and variations.


CODE:

{
    "presets": [
        [
        "next/babel",
        {
            "babel-plugin-transform-imports":
            {
                "@material-ui/core": {
                    // Use "transform: '@material-ui/core/${member}'," if your bundler does not support ES modules
                    "transform": "@material-ui/core/esm/${member}",
                    "preventFullImport": true
                },
                "@material-ui/icons": {
                    // Use "transform: '@material-ui/icons/${member}'," if your bundler does not support ES modules
                    "transform": "@material-ui/icons/esm/${member}",
                    "preventFullImport": true
                }
            }
        }
        ]
    ],
    "plugins": []
}

OR

module.exports = {
    presets: [
        ["next/babel"]
    ],
    plugins: [
         [
             'babel-plugin-import',
             {
                 'libraryName': '@material-ui/core',
                 // Use "'libraryDirectory': ''," if your bundler does not support ES modules
                 'libraryDirectory': 'esm',
                 'camel2DashComponentName': false
             },
             'core'
         ],
         [
             'babel-plugin-import',
             {
                 'libraryName': '@material-ui/icons',
                 // Use "'libraryDirectory': ''," if your bundler does not support ES modules
                 'libraryDirectory': 'esm',
                 'camel2DashComponentName': false
             },
             'icons'
         ],
    ]
}

OR ELSE ?

Upvotes: 5

Views: 5424

Answers (2)

Firoj Siddiki
Firoj Siddiki

Reputation: 1941

I could exactly understand your problem. Follow this.

  1. npm install babel-plugin-import --save-dev

  2. Create a .babelrc file in the root directory of your next.js project with the following content:

{
  "presets": ["next/babel"],
  "plugins": [
      [
      'babel-plugin-import',
      {
        libraryName: '@mui/material',
        libraryDirectory: '',
        camel2DashComponentName: false,
      },
      'core',
    ],
    [
      'babel-plugin-import',
      {
        libraryName: '@mui/icons-material',
        libraryDirectory: '',
        camel2DashComponentName: false,
      },
      'icons',
    ],
  ]
}
  1. Restart your development server.
  • This above babel configuration will convert
// from
import { Button, TextField } from '@mui/material'; ( great developer experience)

// to
import Button from '@mui/material/Button'; (smaller bundle size means great user experience)
import TextField from '@mui/material/TextField';
  • As a result, you will notice
    • faster loading of development server.
    • smaller bundle size
    • also faster client navigation with next/link and fallback:true.

Source: Babel config docs

Mui

Next.js

Hope it works for you too!

Upvotes: 4

TC5
TC5

Reputation: 23

Adding babel-plugin-transform-imports is what worked for me. My .babelrc file looks like this:

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "babel-plugin-transform-imports",
      {
        "@material-ui/core": {
          "transform": "@material-ui/core/${member}",
          "preventFullImport": true
        },
        "@material-ui/icons": {
          "transform": "@material-ui/icons/${member}",
          "preventFullImport": true
        }
      }
    ]
  ]
}

Try using the non-esm version that you have commented out in your implementation. After doing that the build time dropped significantly for me. I did have to update styles imports for Material UI like they recommend in their documentation as well.

Upvotes: 1

Related Questions