Webpack+React配置报错:已设对应插件仍提示需Loader
Webpack + React 配置报错排查与解决
报错信息
开发模式报错
Compiled with problems: × ERROR in ./src/index.js Module build failed (from ./node_modules/babel-loader/lib/index.js): Error: .presets[0][1] must be an object, false, or undefined at Object.loadPartialConfigAsync (/*****/****/******/******/*****/react_props/task_0/dashboard/node_modules/@babel/core/lib/config/index.js:34:85) at Object.loader /*****/****/******/******/*****/react_props/task_0/dashboard/node_modules/babel-loader/lib/index.js:109:30) at Object.<anonymous> (/*****/****/******/******/*****/react_props/task_0/dashboard/node_modules/babel-loader/lib/index.js:39:12)
生产模式报错
ERROR in ./src/index.js 9:2 Module parse failed: Unexpected token (9:2) 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 | const root = ReactDOM.createRoot(document.getElementById('root')); | root.render( > <React.StrictMode> | <App /> | </React.StrictMode>
相关配置文件
webpack.config.js
const path = require('path'); const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const TerserPlugin = require("terser-webpack-plugin"); const isDevelopment = process.env.NODE_ENV !== 'production'; module.exports = { mode: isDevelopment ? 'development' : 'production', entry: path.resolve(__dirname, '../src/index.js'), output: { path: path.resolve(__dirname, './dist'), filename: 'bundle.js', }, resolve: { extensions: ['', '.js', '.jsx'], }, devServer: { static: { directory: path.join(__dirname, "./dist"), serveIndex: true, }, open: true, hot: true, }, devtool: 'inline-source-map', module: { rules: [ { test: /\.css$/i, use: ["style-loader", "css-loader"], }, { test: /\.(png|svg|jpg|jpeg|gif)$/i, use: [ 'file-loader', { loader: 'image-webpack-loader', options: { bypassOnDebug: true, disable: true, }, }, ], }, { test: /\.[jt]sx?$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: [ ["@babel/preset-env", "@babel/preset-react"] ], plugins: ['@babel/plugin-proposal-class-properties'] } } }, ], }, plugins: [ isDevelopment && new ReactRefreshPlugin(), new HtmlWebpackPlugin({ title: 'Holberton Dashboard', template: './dist/index.html', inject: false }), new CleanWebpackPlugin() ], optimization: { minimize: true, minimizer: [ new TerserPlugin(), ], } };
.babelrc
{ "presets": [ ["@babel/preset-react", {"runtime": "automatic"}], [ "@babel/preset-env", { "targets": { "browsers": "last 2 versions" }, "modules": false, "loose": false } ] ], "plugins": [ "react-hot-loader/babel" ], "env": { "test": { "plugins": [ "transform-es2015-modules-commonjs" ] } } }
package.json
{ "name": "dashboard", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "jest", "webpack-dev-server": "webpack-dev-server --config ./config/webpack.config.js", "start-dev": "webpack-dev-server --open", "dev": "webpack serve --mode development", "build": "webpack --mode production" }, "config": { "webpack": "webpack.config.js" }, "author": "", "license": "ISC", "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-script": "^2.0.5" }, "devDependencies": { "@babel/core": "^7.22.11", "@babel/preset-env": "^7.22.14", "@babel/preset-react": "^7.22.5", "@cfaester/enzyme-adapter-react-18": "^0.7.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "babel": "^6.23.0", "babel-cli": "^6.26.0", "babel-loader": "^9.1.3", "babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "clean-webpack-plugin": "^4.0.0", "css-loader": "^6.8.1", "enzyme": "^3.11.0", "file-loader": "^6.2.0", "html-webpack-plugin": "^5.5.3", "image-webpack-loader": "^8.1.0", "jest": "^29.6.4", "react-refresh": "^0.14.0", "style-loader": "^3.3.3", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1" }, "jest": { "setupFiles": [ "<rootDir>/config/setupTests.js" ], "moduleNameMapper": { "\\.(css)$": "<rootDir>/__mocks__/styleMock.js", "\\.(jpg)$": "<rootDir>/__mocks__/fileMock.js", "\\.(png)$": "<rootDir>/__mocks__/fileMock.js" } } }
问题修复方案
1. 开发模式报错修复(.presets[0][1] 错误)
webpack配置中babel-loader的presets写法错误,将两个preset放在同一个数组里不符合语法,需分开为独立数组项。更优的方式是直接复用.babelrc的配置,移除webpack中babel-loader的options,避免重复配置冲突:
// 修改 webpack.config.js 中的babel-loader规则 { test: /\.[jt]sx?$/, exclude: /node_modules/, use: 'babel-loader' // 移除options,让babel自动读取.babelrc }
2. 生产模式报错修复(Unexpected token)
JSX未被正确转译,需调整两处配置:
- webpack 5不支持空字符串作为扩展名,修改resolve配置:
resolve: { extensions: ['.js', '.jsx'] }
- 确保babel通过
.babelrc加载@babel/preset-react,保证JSX被转译为浏览器可识别的代码。
3. 其他配置优化
- 移除package.json中
babel、babel-cli、react-script依赖,这些包与现有@babel 7.x版本冲突或无实际用途; - 修正HtmlWebpackPlugin的template路径,指向src目录下的模板文件(如
./src/index.html),dist为输出目录,开发阶段不存在该文件; - 修复plugins数组的条件判断,避免生产模式下传入无效值:
plugins: [ ...(isDevelopment ? [new ReactRefreshPlugin()] : []), new HtmlWebpackPlugin({ title: 'Holberton Dashboard', template: './src/index.html', inject: 'body' }), new CleanWebpackPlugin() ]
- 生产模式下将devtool改为
source-map,inline-source-map仅适合开发阶段; - 替换
babel-plugin-transform-class-properties为@babel/plugin-proposal-class-properties,保持与@babel 7.x版本兼容。
内容的提问来源于stack exchange,提问作者Raphaël Chemouni
相关产品推荐
相关产品推荐

