From d23f5ea86f37b55116fcb1b791761c240286498c Mon Sep 17 00:00:00 2001 From: Jake Howell Date: Fri, 20 Feb 2026 12:53:18 +1100 Subject: [PATCH] fix: add `optimizeDeps` on `@emotion/*` and `@mui/*` (#22130) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 ``. 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. --- site/vite.config.mts | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/site/vite.config.mts b/site/vite.config.mts index 4319a560f4..46643b0808 100644 --- a/site/vite.config.mts +++ b/site/vite.config.mts @@ -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"),