如何修复引入@mui/x-charts后Webpack构建失败问题?
模块解析错误:处理@mui包中的空值合并运算符(??)失败
问题场景
近期开发新工具时引入@mui/x-charts包,编码测试完成后执行生产构建,持续出现模块解析错误,提示缺少合适的loader处理@mui包内文件(如代码中的??空值合并运算符)。
错误信息
ERROR in ./node_modules/@mui/material/transitions/utils.js 9:40 Module parse failed: Unexpected token (9:40) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders | } = props; | return { > duration: style.transitionDuration ?? (typeof timeout === 'number' ? timeout : timeout[options.mode] || 0), | easing: style.transitionTimingFunction ?? (typeof easing === 'object' ? easing[options.mode] : easing), | delay: style.transitionDelay @ ./node_modules/@mui/material/Slide/Slide.js 13:0-69 122:4-10 128:28-46 150:28-46 @ ./node_modules/@mui/material/Slide/index.js @ ./node_modules/@mui/material/index.js @ ./src/paginas/simuladores/calculadora_juros_compostos/form/index.js @ ./src/paginas/simuladores/calculadora_juros_compostos/index.js @ ./simuladores/simuladores.js
相关配置
package.json
{ "name": "produtos_esb", "version": "0.1.0", "private": true, "main": "index.js", "dependencies": { "@babel/plugin-proposal-class-properties": "^7.16.7", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", "@loadable/component": "^5.15.2", "@mui/x-charts": "^7.19.0", "@sentry/browser": "^5.18.1", "acorn": "^6.0.5", "axios": "^0.26.1", "bootstrap": "^4.6.1", "font-awesome": "^4.7.0", "font-awesome-sass-loader": "^2.0.1", "immutability-helper": "^3.1.1", "react": "^17.0.0", "react-currency-masked-input": "^2.5.0", "react-dom": "^17.0.0", "react-ga": "^3.3.0", "react-google-charts": "^5.1.0", "react-hook-form": "^7.53.0", "react-icons": "^3.11.0", "react-number-format": "^4.9.4", "react-phone-input-2": "^2.15.0", "react-responsive": "^9.0.0", "react-router-dom": "^5.3.1", "react-scripts": "^5.0.1", "react-scroll": "^1.8.7", "react-select": "^3.0.8", "react-sticky-box": "^2.0.5", "react-text-mask": "^5.4.3", "reactstrap": "^8.10.1", "styled-components": "^4.3.2", "text-mask-addons": "^3.8.0", "url-loader": "^2.1.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "local": "webpack --config webpack.config.local.js --mode development", "ts1": "webpack --config webpack.config.ts1.js --mode development", "prod": "webpack --config webpack.config.prod.js --mode production", "prod-sem-hash": "webpack --config webpack.config.prod-sem-hash.js --mode production", "r7": "webpack --config webpack.config.r7.js --mode production", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "@babel/core": "^7.17.9", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/preset-env": "^7.16.11", "@babel/preset-react": "^7.25.7", "@gfx/zopfli": "^1.0.14", "clean-webpack-plugin": "^3.0.0", "compression-webpack-plugin": "^3.1.0", "css-loader": "^3.6.0", "file-loader": "^4.2.0", "style-loader": "^1.0.0", "webpack-cli": "^3.3.6" } }
Webpack配置文件
const path = require('path'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const CompressionPlugin = require('compression-webpack-plugin'); const zopfli = require('@gfx/zopfli'); module.exports = { entry: { app: './simuladores/simuladores.js', }, plugins: [ new CleanWebpackPlugin(), new CompressionPlugin({ compressionOptions: { numiterations: 15, }, algorithm(input, compressionOptions, callback) { return zopfli.gzip(input, compressionOptions, callback); } }), ], output: { path: path.join(__dirname,'..','..','nginx','build'), filename: 'simuladores_[hash].js', chunkFilename: 'sim.chk.[name]_[hash].js', publicPath: 'https://ferramentas.educandoseubolso.com/build/', }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: ['babel-loader'], }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.(png|jpe?g|gif)$/i, use: ['file-loader'], }, { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: ['url-loader?limit=10000&mimetype=application/font-woff'], }, { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: ['file-loader'], }, ], }, optimization: { splitChunks: { cacheGroups: { commons: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all' }, }, }, }, };
解决方案
核心原因
Webpack配置中babel-loader排除了所有node_modules目录,但@mui包内使用了ES2020+语法(如??运算符),当前Babel配置未对这些代码进行转译,导致Webpack无法解析。
具体修复步骤
修改Webpack的babel-loader规则
将原本排除所有node_modules的配置,改为排除除@mui、@emotion之外的依赖,让Babel处理这两个包的代码:{ test: /\.js$/, // 只排除非@mui和@emotion的node_modules内容 exclude: /node_modules\/(?!(@mui|@emotion)\/).*/, use: ['babel-loader'], }完善Babel配置
在项目根目录创建.babelrc文件,或在package.json中添加babel字段,确保Babel支持ES2020+语法及必要的polyfill:"babel": { "presets": [ ["@babel/preset-env", { "useBuiltIns": "usage", "corejs": 3 }], "@babel/preset-react" ], "plugins": [ "@babel/plugin-proposal-class-properties", "@babel/plugin-syntax-dynamic-import" ] }@babel/preset-env会根据browserslist自动转译目标浏览器不支持的语法,corejs用于补充必要的polyfill。验证依赖兼容性
@mui/x-charts@7.19.0官方文档显示支持React17.0.0,若仍有问题可考虑降级到适配版本,但优先尝试前两步方案。重新构建
修改配置后执行生产构建命令,检查错误是否消除。若仍有类似语法错误,可将其他使用未转译ES6+代码的依赖添加到exclude的例外列表中。
内容的提问来源于stack exchange,提问作者Loizm
相关产品推荐
相关产品推荐

