I've created a monorepo with a shared component library, but when I import components from that library that contain a MUI icon from @mui/icons-material I get the following error:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

This is what I get when I console.log() an imported Icon

import AddIcon from '@mui/icons-material/Save';
console.log(AddIcon)

{
  default: {
    '$$typeof': Symbol(react.memo),
    type: { '$$typeof': Symbol(react.forward_ref), render: [Function] },
    compare: null
  }
}

Everything else in the shared components is working fine, including the regular MUI components, and the icons work normally if I'm just adding them directly to my project so I can't figure out why they break in the shared components.

I have "@mui/icons-material": "^5.6.1" in the peerDependencies of my shared library and "@mui/icons-material": "^5.6.1" as a dependency in the project that I'm importing the shared components to.

3

There are 3 answers

0
IanLancaster On

Ran into the same issue using MUI with the turbo repo design starter (tsup). I don't like this hack, but it does appear to work.

import SaveBase from '@mui/icons-material/Save';
import SvgIcon from '@mui/material/SvgIcon/SvgIcon';

const normalizeIcon = (Icon: typeof SvgIcon) => {
  return ((Icon as any).default ? (Icon as any).default : Icon) as typeof SvgIcon;
};

const SaveIcon = normalizeIcon(SaveBase);

<SaveIcon />
0
fszlin On

Changing the import also works for me.

from

// import ([\w]+) from '@mui/icons-material/([\w]+)'
import MenuIcon from '@mui/icons-material/Menu';

to

// import { $2 as $1 } from '@mui/icons-material'
import { Menu as MenuIcon } from '@mui/icons-material';
0
mycroes On

I built my packages with both commonjs and es modules. I have the commonjs in the root of the package and es modules in an esm/ subdirectory. In my esm/ subdirectory I have a package.json with just {"type": "module"}. I'm not using exports in the root package.json, but just main and module where module points to ./esm/index.js. The output in esm/ actually is the result of tsc --target es6 --module esnext --outDir ./build/esm.

With package.json in esm/ subdirectory I get the exact error you pointed out and the icon import will be an object with default that points to the expected imported data. However, if I delete the package.json in esm/ all is fine again. It also seems to greatly reduce startup time, so I'm guessing something is broken in my package setup.

I'm not sure if this also applies to you, but the symptons are definitely the same.