mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.76k stars 32.25k forks source link

Uncaught TypeError: SvgIcon_default is undefined with vite in dev mode after @mui/icons-material@6.1.0+ #44180

Open cmdcolin opened 5 days ago

cmdcolin commented 5 days ago

Steps to reproduce

Link to live example: (required) https://github.com/cmdcolin/mui-icons-material-error-repro

Steps:

  1. clone the repo
  2. run yarn
  3. run yarn dev
  4. observe dev tools error "Uncaught TypeError: SvgIcon_default is undefined"
  5. you can optionally checkout the commit HEAD~1 (at which i made a commit message "works") to show that it actually works in a case depending on order of the import of @mui/icons-material/Menu. you can additionally optionally apply a yarn resolution to get @mui/icons-material@6.0.2 to make it work.

Current behavior

The app fails to run in dev mode in vite due to a fatal error, and it appears to be related to the inclusion of our library and is sensitive to the order of import of the @mui/icons-material/Menu component.

Expected behavior

ideally we should be able to use our library, and not have sensitivity to order of imports.

Context

See the README in https://github.com/cmdcolin/mui-icons-material-error-repro for some technical context

The repro is a minimal "App" that only renders a single <Menu/> from @mui/icons-material/Menu, but it includes a function from our library also. I am using yarn v1 as a package manager and latest vite.

The error seems to appear only when our NPM package @jbrowse/react-linear-genome-view is used, and it is sensitive to the order of @mui/icons-material imports. our library uses @mui/material v6 including @mui/icons-material v6 as well. I found that @mui/icons-material@6.1.0+ introduced the above error. I saw that https://github.com/mui/material-ui/issues/31835 could be related (xref also https://github.com/mui/material-ui/pull/43624)

ideally, that PR should be a positive for helping most people but it seems to have caused issues with using our library in vite. I am not aware of anything particularly weird that @jbrowse/react-linear-genome-view does regarding imports, we always import from the full path e.g. '@mui/icons-material/Menu' not the barrel style {Menu} from '@mui/icons-material', but wasn't able to create a more minimal repro just yet. our library is not pure ESM.

if it seems like fixing this or hunting this down would be too complex, or making a proper fix would compromise other peoples setups more, then you can ignore this or wontfix it, i won't be upset :)

Your environment

npx @mui/envinfo System: OS: Linux 6.11 Ubuntu 24.10 24.10 (Oracular Oriole) Binaries: Node: 22.8.0 - /run/user/1001/fnm_multishells/17235_1729569485832/bin/node npm: 10.8.2 - /run/user/1001/fnm_multishells/17235_1729569485832/bin/npm pnpm: Not Found Browsers: Chrome: 127.0.6533.72 npmPackages: @emotion/react: 11.13.3 @emotion/styled: 11.13.0 @mui/core-downloads-tracker: 6.1.4 @mui/icons-material: 6.1.4 @mui/material: 6.1.4 @mui/private-theming: 6.1.4 @mui/styled-engine: 6.1.4 @mui/system: 6.1.4 @mui/types: 7.2.18 @mui/utils: 6.1.4 @mui/x-charts-vendor: 7.20.0 @mui/x-data-grid: 7.21.0 @mui/x-internals: 7.21.0 @types/react: ^18.0.26 => 18.3.11 react: ^18.2.0 => 18.3.1 react-dom: ^18.2.0 => 18.3.1 typescript: ^5.1.6 => 5.6.3 I also used Firefox but chrome is the same (chrome makes the slightly different error message 'Cannot read properties of undefined (reading 'muiName')')

Search keywords: esbuild, vite, @mui/icons-material

cmdcolin commented 5 days ago

random extra debugging:

this might be due to esbuild using our "commonjs" distribution. our commonjs build is created by using tsc with "target":"commonjs". we also have a "esm-style" distribution using the package.json "module" field (not type:"module" but the non-standard module field recognized by webpack and others), but this might be unused by esbuild.

the commonjs esm compatibility created by the typescript tsc compilation looks like this with the __importDefault helper

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
...
const Visibility_1 = __importDefault(require("@mui/icons-material/Visibility"));

if i change the package.json "main" to be our "module" field, then the code works, which leads me to believe that the main was being used by esbuild, and thus, the complicated esm compat layer listed above

all this should "ideally work" but i know esm and commonjs is often at odds