mui / material-ui

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

[ESM] Publish packages in ESM module format #30671

Open Janpot opened 2 years ago

Janpot commented 2 years ago

Why

How

MicahZoltu commented 2 years ago

Internal imports will need file extensions https://github.com/jaydenseric/babel-plugin-transform-require-extensions

I think this should probably be extracted out into a separate issue, as it would be a boon to using Material UI natively in a browser (without a bundler/transpiler), I think even without addressing the other things mentioned here (I could be wrong though).

cseas commented 1 year ago

Publint is reporting that the components are written in ESM but getting interpreted as CJS.

Screenshot 2023-02-23 at 12 51 47 PM

I tried the MUI imports in a Next.js project with type: module and moduleResolution: node16 though, seems to work fine. (https://codesandbox.io/p/sandbox/angry-benji-oi33ry)

Is this because Next.js is reading the CJS exports under node/ directory instead of ESM ones?

zbynekwinkler commented 1 year ago

In order to be able to use @mui/icons-material in ES module (with remix), I had to use named import:

import { LockOutlined } from '@mui/icons-material';

I believe it relies on the presence of "module": "./esm/index.js" field in the installed package.json which reexports everything. Reaching out to @mui/icons-material/LockOutlinedIcon like the examples do, fails.

samuelsycamore commented 1 year ago

This seems to be a blocker for getting MUI components to play nicely with Remix. Named imports appear to work fine.

❌ import Box from "@mui/joy/Box";
✅ import { Box } from "@mui/material";
cjoecker commented 1 year ago

As a workaround, you can do for now the following search-and-replace with regex to fix it: Search import (.*)Icon from "@mui/icons-material/(.*)"; and replace with import { $1 as $1Icon } from "@mui/icons-material";

akomm commented 9 months ago

Output .cjs file, set it under package.json should make it possible use it with tsconfig esModuleInterop: true. Currently you can't do anything in esm configured project, because there is just a .js file in the build. And this .js file uses esm syntax.

Having this issue with the AdapterXYZ exports - date-pickers.

oliviertassinari commented 8 months ago

Requirement for both CommonJS and ESM support from Docker: https://app.supernormal.com/posts/mui-docker-x-charts-6b722290c9c8013c6d350e8110019023

SCR-20240404-pida
Janpot commented 7 months ago

Would be interested in what those infrastructure requirements are exactly. What mandates the need for a commonjs bundle? Does their bundler not understand ESM? Or does their SSR setup not compile modules on the server? It's an odd choice to try and fix this by adding a commonjs version to their chart library, rather than to force their bundler to transpile the dependency.

DiegoAndai commented 6 months ago

Sadly, I'm removing this issue from the v6 milestone, tentatively moving it to v7. I'll write an in-depth document on what we tried, why we're blocked, and the steps forward. As a summary, we found a blocker with Next.js Pages Router: https://github.com/vercel/next.js/issues/65056. The probable path forward is removing the esmExternals: false from our documentation infra, but that's currently blocked by https://github.com/vercel/next.js/issues/49898#issuecomment-1762202697.

esmExternal was added in https://github.com/mui/material-ui/pull/37264#issuecomment-1551116576.

Janpot commented 3 months ago

Just recording some tips for anyone that wants to debug this:

It looks like webpack isn't using the ESM bundle of @mui/x-data-grid. We may be able to fix this by:

akomm commented 3 months ago

Currently the issue is maximized in the sense of blocking every possible simple workaround at once, by exporting .js, not .cjs (for interop workaround TS) or .mjs and at the same time using esm syntax in the .js build:

https://github.com/mui/material-ui/issues/30671#issuecomment-1941097296

main points to .js: grafik

ESM syntax in .js output: grafik

justin-hackin commented 1 month ago

I've gotten used to copy-pasting icons from the website into my project. I forgot about this issue and accidentally broke my app in dev. That's why I went out of my way to prevent this from happening in the future by adding an eslint rule to prevent imports of the icons as in the copypasta:

       "no-restricted-imports": ["error", {
          "patterns": [{
            "group": ["@mui/icons-material/*"],
          }]
        }]