fix: add optimizeDeps on @emotion/* and @mui/* (#22130)

This PR stops Vite from repeatedly re-optimizing certain MUI modules
during development, which was triggering an HMR feedback loop and
crashing my dev environment on specific pages — most notably
`<LicensesSettingsPage />`.

After some digging, the culprit turned out to be:

```ts
import Paper from "@mui/material/Paper";
```

Importing components this way causes Vite to continuously re-optimize
them during HMR, which leads to the page refreshing over and over until
the dev server taps out and `504 "Outdated Optimize Dep"`'s us.

The fix ensures these modules are computed once at startup instead of
being reprocessed on every hot update. Development is now stable, and
the infinite refresh loop is gone.

I did experiment with using globs to handle this more generically, but
since they’re still early-access in this context, they ended up breaking
things 😔

In short: fewer re-optimizations, no more HMR meltdown, and a much
calmer dev experience.
This commit is contained in:
Jake Howell
2026-02-20 12:53:18 +11:00
committed by GitHub
parent e857060010
commit d23f5ea86f
+66
View File
@@ -119,6 +119,72 @@ export default defineConfig({
},
allowedHosts: [".coder", ".dev.coder.com"],
},
// Pre-bundle deps that Vite tends to discover late (deep MUI
// imports, Emotion). Without this, Vite re-optimizes mid-session
// which returns 504 "Outdated Optimize Dep" for every previously
// served chunk, cascading into dynamic import failures.
optimizeDeps: {
include: [
"@emotion/cache",
"@emotion/css",
"@emotion/react",
"@emotion/react/jsx-runtime",
"@emotion/styled",
"@mui/material/Alert",
"@mui/material/AlertTitle",
"@mui/material/Autocomplete",
"@mui/material/Card",
"@mui/material/CardActionArea",
"@mui/material/CardContent",
"@mui/material/Checkbox",
"@mui/material/Chip",
"@mui/material/CircularProgress",
"@mui/material/Collapse",
"@mui/material/CssBaseline",
"@mui/material/Dialog",
"@mui/material/DialogActions",
"@mui/material/DialogContent",
"@mui/material/DialogContentText",
"@mui/material/DialogTitle",
"@mui/material/Divider",
"@mui/material/Drawer",
"@mui/material/FormControl",
"@mui/material/FormControlLabel",
"@mui/material/FormGroup",
"@mui/material/FormHelperText",
"@mui/material/FormLabel",
"@mui/material/Grid",
"@mui/material/IconButton",
"@mui/material/InputAdornment",
"@mui/material/InputBase",
"@mui/material/LinearProgress",
"@mui/material/Link",
"@mui/material/List",
"@mui/material/ListItem",
"@mui/material/ListItemText",
"@mui/material/Menu",
"@mui/material/MenuItem",
"@mui/material/MenuList",
"@mui/material/Paper",
"@mui/material/Radio",
"@mui/material/RadioGroup",
"@mui/material/Select",
"@mui/material/Skeleton",
"@mui/material/Snackbar",
"@mui/material/Stack",
"@mui/material/SvgIcon",
"@mui/material/Switch",
"@mui/material/TableRow",
"@mui/material/TextField",
"@mui/material/ToggleButton",
"@mui/material/ToggleButtonGroup",
"@mui/material/styles",
"@mui/material/useMediaQuery",
"@mui/system/createTheme",
"@mui/system/useTheme",
"@mui/x-tree-view",
],
},
resolve: {
alias: {
App: path.resolve(__dirname, "./src/App"),