React 16→17、MUI 4→5迁移:MUI X Date Picker编译错误求助
问题背景
在将monorepo应用从React 16迁移至React 17、同时完成MUI 4到MUI 5升级的过程中,其余功能运行正常,但使用MUI 5日期选择器时出现以下编译错误:
../node_modules/@mui/x-date-pickers/LocalizationProvider/LocalizationProvider.js 36:50
Module parse failed: Unexpected token (36:50)
File was processed with these loaders:
- ../../node_modules/react-scripts/node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| utils: parentUtils,
| localeText: parentLocaleText} = React.useContext(MuiPickersAdapterContext) ?? {
| utils: undefined,
| localeText: undefined
关键环境信息
- 构建工具:
react-scripts@3.4.4(内置webpack@4.42.0),项目同时存在webpack@4.46.0 - 使用
react-app-rewired,config-overrides.js配置:
module.exports = function override(webpackConfig) { webpackConfig.module.rules.push({ test: /\.mjs$/, include: /node_modules/, type: 'javascript/auto', }); return webpackConfig; };
.babelrc配置:
{"presets": [["@babel/preset-env", {"modules": false}],"@babel/preset-react","@babel/preset-typescript"],"plugins": [["@babel/plugin-proposal-decorators", { "legacy": true }], "@babel/plugin-proposal-class-properties","@babel/plugin-proposal-export-default-from","@babel/plugin-proposal-optional-chaining",["module-resolver", {"alias": {"ux": "./src/ux","components": "./src/components","pages": "./src/pages"}}]],"ignore": ["src/static/pdfjs-2.0.943-dist"]}
- MUI X日期选择器版本:
@mui/x-date-pickers@^7.2.0
已尝试升级react-scripts到5.x但出现大量node_modules导入错误,添加@babel/plugin-transform-nullish-coalescing-operator插件未解决问题。
可行解决方案
方案1:降级@mui/x-date-pickers到兼容webpack 4的版本
MUI X v7+使用了更现代的JS语法(如空值合并运算符??),而webpack 4配合旧版构建工具无法正确处理未转译的node_modules代码。降级到MUI X v6版本可解决兼容性问题:
npm install @mui/x-date-pickers@^6.19.0 # 或使用yarn yarn add @mui/x-date-pickers@^6.19.0
- 注意:v6版本与你当前的
@mui/material@5.15.15完全兼容,同时确保@date-io/moment适配器版本匹配(v6支持@1.x和@2.x版本)。
方案2:配置react-app-rewired让Babel转译@mui/x-date-pickers
默认情况下create-react-app不会转译node_modules中的包,修改config-overrides.js让babel-loader处理@mui/x-date-pickers相关文件:
module.exports = function override(webpackConfig) { // 保留原有处理.mjs的规则 webpackConfig.module.rules.push({ test: /\.mjs$/, include: /node_modules/, type: 'javascript/auto', }); // 添加转译@mui/x-date-pickers的规则 const babelRule = webpackConfig.module.rules.find(rule => rule.oneOf && rule.oneOf.some(subRule => subRule.loader?.includes('babel-loader')) ); if (babelRule) { babelRule.oneOf.forEach(subRule => { if (subRule.loader?.includes('babel-loader')) { // 排除node_modules但包含@mui/x-date-pickers subRule.exclude = /node_modules(?!\/@mui\/x-date-pickers)/; } }); } return webpackConfig; };
同时确保.babelrc中添加@babel/plugin-proposal-nullish-coalescing-operator插件:
{ "presets": [["@babel/preset-env", {"modules": false}], "@babel/preset-react", "@babel/preset-typescript"], "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": true }], "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-export-default-from", "@babel/plugin-proposal-optional-chaining", "@babel/plugin-proposal-nullish-coalescing-operator", ["module-resolver", {"alias": {"ux": "./src/ux","components": "./src/components","pages": "./src/pages"}}] ], "ignore": ["src/static/pdfjs-2.0.943-dist"] }
方案3:更新Babel核心依赖到兼容版本
你的@babel/preset-env@7.4.5版本过旧,无法很好支持现代语法转译,更新相关依赖:
npm install @babel/core@^7.20.0 @babel/preset-env@^7.20.0 @babel/plugin-proposal-nullish-coalescing-operator@^7.18.6 --save-dev # 或使用yarn yarn add @babel/core@^7.20.0 @babel/preset-env@^7.20.0 @babel/plugin-proposal-nullish-coalescing-operator@^7.18.6 --dev
更新后重启构建流程,确保Babel能正确转译空值合并运算符等现代语法。
内容的提问来源于stack exchange,提问作者Alejo90

