Material UI with styled-components and Vite/Vitest is not working since v7
Steps to reproduce
After migrating to mui v7, the unit tests running on Vitest are not working anymore:
Steps:
- Open this link to live example: https://stackblitz.com/~/github.com/woodreamz/mui7-scStyled-issue (or https://github.com/woodreamz/mui7-scStyled-issue)
- Run
npm install - Run
npm run test
Current behavior
This error appears:
Expected behavior
It should work like mui 6.
Context
I am using Vite + Vitest with Mui7 and styled-components. I usually use pnpm but to simplify the thing, I used npm. By the way the Using styled-components is not accurate when you work with Vite + Vitest, you must also override styled-engine in the package.json otherwise vitest resolves styled-engine instead of styled-engine-sc.
There is a workaround to make it work. You need to add the fallbackCJS this in your vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";
// https://vite.dev/config/
export default defineConfig({
test: {
environment: "jsdom",
globals: true,
// #region Uncomment this code to work with Mui v7+
server: {
deps: {
fallbackCJS: true,
},
},
// #endregion
},
plugins: [react(), tsconfigPaths()],
});
I also have a premium license, I don't know if it's required for the mui support.
Thank you!
Your environment
npx @mui/envinfo
System:
OS: macOS 14.1.1
Binaries:
Node: 22.16.0 - ~/.nvm/versions/node/v22.16.0/bin/node
npm: 10.9.2 - ~/.nvm/versions/node/v22.16.0/bin/npm
pnpm: 9.9.0 - ~/Library/pnpm/pnpm
Browsers:
Chrome: 138.0.7204.158
Edge: Not Found
Safari: 17.1
npmPackages:
@mui/core-downloads-tracker: 7.2.0
@mui/material: ^7.2.0 => 7.2.0
@mui/private-theming: 7.2.0
@mui/styled-engine-sc: 7.2.0
@mui/system: 7.2.0
@mui/types: 7.4.4
@mui/utils: 7.2.0
@types/react: ^19.1.8 => 19.1.8
react: ^19.1.0 => 19.1.0
react-dom: ^19.1.0 => 19.1.0
styled-components: ^6.1.19 => 6.1.19
typescript: ~5.8.3 => 5.8.3
Search keywords: vitest mui7 styled-components
Thanks for reporting the issue. I can reproduce it and it looks like ESM/CJS from styled-components itself.
What you did is the way to fix it.
export default defineConfig({
test: {
environment: "jsdom",
globals: true,
server: {
deps: {
fallbackCJS: true,
},
},
},
plugins: [react(), tsconfigPaths()],
});
It can be reproduced by disabling https://vitest.dev/config/#deps-interopdefault, and create a component using styled-components directly.
We need to add Vite configuration to https://mui.com/material-ui/integrations/styled-components/
@siriwatknp This solution is working, but it's very slow. Is there any way to improve performance?
You can also resolve this issue by using inline deps, though I haven’t tested whether it’s faster than fallbackCJS:
test: {
server: {
deps: {
inline: [
'@mui/material',
'@mui/system',
'@mui/styled-engine',
'@mui/icons-material',
/* remove this line if you aren't using date pickers */
'@mui/x-date-pickers',
],
},
},
}
I also tried to fix the issue in @mui/styled-engine-sc locally and changing the import from default to named here seems to fix it.
When I'm changing it to
import { styled as scStyled } from 'styled-components';
it works without the server.deps.inline changes. But I can't really tell why the default import isn't working in Vitest.
The solutions mentioned here don’t seem to work on Windows (tried two windows machine to validate)...the tests still fail, even with fallbackCJS and inline dependencies.
Is there a plan to address this? My tests are currently failing, and nothing I’ve tried has worked so far.
@Nico142 I also tried to fix the issue in
@mui/styled-engine-sclocally and changing the import from default to named here seems to fix it. When I'm changing it toimport { styled as scStyled } from 'styled-components';
it works without the
server.deps.inlinechanges. But I can't really tell why the default import isn't working in Vitest.
I can confirm that changing it, it does indeed fix as well (without adding server.deps.fallbackCJS: true) the issue in Windows:
But in our project, I found other problems more MUI related:
To get rid of those errors, I have to:
-
Edit
node_modules/@mui/styled-engine-sc/src/index.js- import scStyled from 'styled-components'; + import { styled as scStyled } from 'styled-components'; -
Add this in vite/vitest config
// vite.config.ts export default defineConfig({ test: { // Prefer inlining MUI packages over fallbackCJS on Windows server: { deps: { inline: [ '@mui/icons-material', '@mui/material', '@mui/x-charts', '@mui/x-data-grid', '@mui/x-data-grid-premium', '@mui/x-date-pickers', '@mui/x-tree-view-pro', ], }, }, }, });
We agree that, since there is no official fix from MUI (Cc: @siriwatknp), patching the package (using patch-package is not really a nice fix... :confused:
For info,
@Nico142 You can also resolve this issue by using inline deps, though I haven’t tested whether it’s faster than
fallbackCJS
We did an empirical test with our library (wrapping/overriding CSS MUI components), it's doubling the speed just by using the inline fix...
- Windows with
import { styled as scStyled } from 'styled-components';+test.server.deps.inline - WSL/Ubuntu with just
fallbackCJS
Note: there is maybe some performance difference based on the PC architecture (Windows vs Ubuntu), so take these values with a grain of salt!
Hey, I'd like to work on this issue. Can I take it
Good catch on improving test coverage! I have experience with testing and would be interested in helping. Which modules or functions need tests most urgently?
Can someone explain why those configurations work? They seem to fix the issue, but what is the actual root cause and why does it happen?