生产构建时MUI Styled代理触发Uncaught TypeError问题
const system = new Proxy(muiSystem, {
get(target, prop, receiver) {
if (prop === 'styled') {
const styled = Reflect.get(target, prop, receiver);
return function (...args: Parameters<CreateMUIStyled>) { const newOptions = getComposedOptions(args[1]); const newArgs: MUIStyledParams = [...args]; newArgs.splice(1, 1, newOptions); const styledResult = styled(...newArgs); return function ( ...newestArgs: Parameters<ReturnType<CreateMUIStyled>> ) { return styledResult(...newestArgs); }; }; } return undefined;
},
});
export const styled = system.styled;
这段代码在Vite开发服务器中运行正常,但生产构建时出现报错: > Uncaught TypeError: 'get' on proxy: property 'styled' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '(o,s={})=>{n6e 为何本地正常生产环境报错?有什么解决办法? ## 原因分析 生产环境下,Vite的Tree Shaking或压缩工具会对`@mui/system`的导出做优化,将`styled`标记为**只读且不可配置的数据属性**。根据ES规范,代理这类属性时,`get`陷阱必须返回目标对象的原始值,否则会触发类型错误。开发环境没有这类严格的代码优化,因此不会触发报错。 ## 解决办法 ### 方案1:直接包装原函数(推荐) 放弃使用Proxy,直接导出包装后的`styled`函数,彻底绕过代理带来的限制: ```typescript import * as muiSystem from '@mui/system'; type CreateMUIStyled = typeof muiSystem.styled; type MUIStyledParams = Parameters<CreateMUIStyled>; // 直接获取原函数 const originalStyled = muiSystem.styled; // 包装并导出自定义styled export const styled = function (...args: MUIStyledParams) { const newOptions = getComposedOptions(args[1]); const newArgs: MUIStyledParams = [...args]; newArgs.splice(1, 1, newOptions); const styledResult = originalStyled(...newArgs); return function ( ...newestArgs: Parameters<ReturnType<CreateMUIStyled>> ) { return styledResult(...newestArgs); }; };
这种方式更直接,也避免了Proxy与生产环境代码优化的冲突问题。
方案2:调整Proxy的get陷阱(不推荐)
如果必须保留Proxy,需要确保get陷阱返回的函数与原属性的特性匹配。可以通过Object.defineProperty复制原函数的描述符到包装函数上,但这种方式复杂度高,且容易因MUI内部实现变更而失效,因此不推荐。
内容的提问来源于stack exchange,提问作者Mister Epic
相关产品推荐
相关产品推荐

