MUI DataGrid内联renderCell正常运行,但提取为自定义组件后在Laravel+React+Inertia生产环境失效
最近我在Laravel + Inertia + React的项目里用MUI DataGrid做表格时,踩了个特别诡异的坑:把操作列的JSX从renderCell里抽成独立组件后,开发环境完全正常,但生产环境直接报500内部服务器错误。给大家梳理下问题细节和排查解决的方向:
正常工作的场景(内联JSX)
在DataGrid的最后一列(操作列),我直接在renderCell里写按钮组,不管是开发环境还是生产部署后,都能正常渲染:
renderCell: () => ( <Stack direction="row" spacing={1} justifyContent="center"> <Tooltip title="Edit"> <IconButton color="warning"> <span style={{ fontSize: '1.2rem' }}>Edit</span> </IconButton> </Tooltip> <Tooltip title="View"> <IconButton color="primary"> <span style={{ fontSize: '1.2rem' }}>View</span> </IconButton> </Tooltip> </Stack> )
出问题的场景(提取为外部组件)
为了代码复用,我把完全一样的JSX抽成了ProjectTableActions.jsx组件:
// ProjectTableActions.jsx import React from 'react'; import { Stack, Tooltip, IconButton } from '@mui/material'; const ProjectTableActions = () => ( <Stack direction="row" spacing={1} justifyContent="center"> <Tooltip title="Edit"> <IconButton color="warning"> <span style={{ fontSize: '1.2rem' }}>Edit</span> </IconButton> </Tooltip> <Tooltip title="View"> <IconButton color="primary"> <span style={{ fontSize: '1.2rem' }}>View</span> </IconButton> </Tooltip> </Stack> ); export default ProjectTableActions;
然后在renderCell里引用这个组件:
renderCell: () => <ProjectTableActions />
结果开发环境好好的,生产环境直接500报错,而且npm run build过程完全没有错误提示,服务器日志(OVH共享主机Apache)只显示模糊的Premature end of script headers: index.php。
关键前提
这个抽出来的组件是纯纯的UI组件:没有状态管理、没有副作用、不接收任何props,就是两个按钮的布局而已,完全排除了业务逻辑导致报错的可能。
排查&解决方向
这种开发/生产环境不一致的问题,基本都是打包配置、缓存或者服务器环境的锅,我整理了几个有效的排查步骤:
1. 先清Laravel的所有缓存
生产环境Laravel的各种缓存很容易搞事情,部署后先跑一遍清缓存命令:
php artisan cache:clear php artisan config:clear php artisan route:clear php artisan view:clear php artisan optimize:clear
很多时候清完缓存问题就直接消失了!
2. 检查Vite的生产打包配置
Laravel + Vite的项目里,生产打包的tree-shaking或者minify可能把组件误处理了,试试临时调整vite.config.js的build配置:
// vite.config.js export default defineConfig({ plugins: [ laravel({ input: 'resources/js/app.jsx', refresh: true, }), react() ], build: { // 临时禁用minify或者tree-shaking,测试是不是打包优化的问题 minify: false, treeShake: false, } });
如果禁用后生产环境正常了,那就是minify/tree-shaking的配置和组件不兼容,可以换用terser代替默认的esbuild,或者调整具体的minify参数。
3. 改组件的导出/导入方式
有时候默认导出在生产打包时会有兼容问题,试试改成命名导出:
// ProjectTableActions.jsx export const ProjectTableActions = () => (/* ... */); // 使用组件的时候用命名导入 import { ProjectTableActions } from './ProjectTableActions';
4. 检查服务器文件权限
OVH共享主机的文件权限经常有坑,确保public/build目录和里面的生成文件权限正确(一般目录755,文件644):
chmod -R 755 public/build chmod -R 644 public/build/*
5. 查看Laravel的详细错误日志
服务器的Premature end of script headers太模糊了,一定要看Laravel自己的日志(storage/logs/laravel.log),里面会有具体的报错信息,比如“找不到组件”“依赖缺失”之类的,这才是定位问题的关键!
总结
这种问题看起来诡异,但其实都是环境差异导致的,按上面的步骤一步步排查,基本都能快速解决。我自己最后是清了Laravel缓存+调整Vite的minify配置搞定的。
内容来源于stack exchange

