如何让Remix与React Material UI图标正常兼容?
Remix + MUI 图标功能触发Lambda超时5秒问题
问题描述
基于Remix+React Material做POC(主应用技术栈一致),大部分功能正常,但图标功能无法工作。带有图标的页面会陷入挂起状态,Remix抛出错误:
Lambda :\Users\chanp\git\my-remix-app\server timed out after 5 seconds
相关代码
entry.client.tsx(参考半官方Remix+MUI应用修改,适配React 18的hydrateRoot):
import { CacheProvider } from "@emotion/react"; import CssBaseline from "@mui/material/CssBaseline"; import { ThemeProvider } from "@mui/material/styles"; import * as React from "react"; import { useState } from "react"; import { hydrate } from "react-dom"; import { RemixBrowser } from "@remix-run/react"; import createEmotionCache from "./createEmotionCache"; import ClientStyleContext from "./styles/ClientStyleContext"; import muiTheme from "./styles/muiTheme"; import { ThemeProvider as EmotionThemeProvider } from "@emotion/react"; import Layout from "./src/components/Layout"; import { hydrateRoot } from "react-dom/client"; const container = document.getElementById("app"); // const root = hydrateRoot(container, <App tab="home" />); interface ClientCacheProviderProps { children: React.ReactNode; } function ClientCacheProvider({ children }: ClientCacheProviderProps) { const [cache, setCache] = useState(createEmotionCache()); function reset() { setCache(createEmotionCache()); } return ( <ClientStyleContext.Provider value={{ reset }}> <CacheProvider value={cache}>{children}</CacheProvider> </ClientStyleContext.Provider> ); } hydrateRoot( document, <ClientCacheProvider> <EmotionThemeProvider theme={muiTheme}> <ThemeProvider theme={muiTheme}> {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */} <CssBaseline /> <RemixBrowser /> </ThemeProvider> </EmotionThemeProvider> </ClientCacheProvider>, );
版本信息
- React v18.2
- Remix v1.6
- 其他核心依赖版本:
{ "@emotion/react": "^11.10.0", "@emotion/styled": "^11.10.0", "@mui/icons-material": "^5.8.4", "@mui/lab": "^5.0.0-alpha.93", "@mui/material": "^5.9.3", "@mui/styled-engine-sc": "^5.9.3", "@mui/styles": "^5.9.3", "@mui/x-date-pickers": "^5.0.0-beta.4" }
不确定还需提供哪些信息,请告知。
解决方案
1. 仅在客户端渲染MUI图标
MUI图标组件在服务端渲染时,可能因动态文件读取、SVG处理逻辑触发超时。可以用Remix生态的clientOnly工具,让图标仅在客户端加载:
// 封装通用客户端图标组件 import { clientOnly } from "remix-utils"; export const ClientHomeIcon = clientOnly(() => import("@mui/icons-material/Home")); // 组件内使用 <ClientHomeIcon />
2. 校验服务端Emotion缓存配置
确保entry.server.tsx中Emotion缓存处理正确,避免服务端渲染阻塞:
// entry.server.tsx示例 import { renderToString } from "react-dom/server"; import { RemixServer } from "@remix-run/react"; import type { EntryContext } from "@remix-run/node"; import { CacheProvider } from "@emotion/react"; import createEmotionCache from "./createEmotionCache"; import { ThemeProvider } from "@mui/material/styles"; import muiTheme from "./styles/muiTheme"; import CssBaseline from "@mui/material/CssBaseline"; export default function handleRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, remixContext: EntryContext ) { const cache = createEmotionCache(); const html = renderToString( <CacheProvider value={cache}> <ThemeProvider theme={muiTheme}> <CssBaseline /> <RemixServer context={remixContext} url={request.url} /> </ThemeProvider> </CacheProvider> ); const styles = cache.inserted; responseHeaders.set("Content-Type", "text/html"); return new Response(`<!DOCTYPE html><html><head>${styles}</head><body>${html}</body></html>`, { status: responseStatusCode, headers: responseHeaders, }); }
3. 升级依赖版本
当前Remix v1.6版本较旧,与MUI的兼容性在后续版本中有优化。建议升级Remix到稳定新版本,同步匹配MUI相关依赖版本。
4. 临时调整Lambda超时配置
若以上方案暂未生效,可临时将Lambda函数超时时间从5秒延长至10秒,但这仅为应急方案,优先解决代码层面问题。
内容的提问来源于stack exchange,提问作者cphilpot
相关产品推荐
相关产品推荐

