You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复引入@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无法解析。

具体修复步骤

  1. 修改Webpack的babel-loader规则
    将原本排除所有node_modules的配置,改为排除除@mui、@emotion之外的依赖,让Babel处理这两个包的代码:

    {
      test: /\.js$/,
      // 只排除非@mui和@emotion的node_modules内容
      exclude: /node_modules\/(?!(@mui|@emotion)\/).*/,
      use: ['babel-loader'],
    }
    
  2. 完善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。

  3. 验证依赖兼容性
    @mui/x-charts@7.19.0官方文档显示支持React17.0.0,若仍有问题可考虑降级到适配版本,但优先尝试前两步方案。

  4. 重新构建
    修改配置后执行生产构建命令,检查错误是否消除。若仍有类似语法错误,可将其他使用未转译ES6+代码的依赖添加到exclude的例外列表中。

内容的提问来源于stack exchange,提问作者Loizm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:02:07