Webpack 5+React项目使用<Routes/>组件触发浏览器内存溢出问题
问题描述
我有一个基于Webpack 5和React的项目,当不使用*
*组件时,执行return (<Routes/>)
npm run dev启动项目一切正常,但一旦使用该组件,浏览器就会显示“Out of Memory”错误,而启动npm脚本的控制台无任何报错。我已尝试过node --max-old-space-size=x命令,当前环境为node v18.16.0、npm 9.5.1。项目配置文件
package.json
{ "name": "client", "version": "1.0.0", "private": true, "type": "commonjs", "scripts": { "dev": "cross-env NODE_ENV=development webpack serve --mode development --open", "build": "cross-env NODE_ENV=production webpack --mode production", "stats": "webpack --json > stats.json && webpack-bundle-analyzer stats.json", "lint": "eslint ./src" }, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ], "author": "Pasha Makarenko", "license": "ISC", "devDependencies": { "@babel/core": "latest", "@babel/eslint-parser": "latest", "@babel/polyfill": "latest", "@babel/preset-env": "latest", "@babel/preset-react": "latest", "@babel/preset-typescript": "latest", "@reduxjs/toolkit": "latest", "@types/react": "latest", "@types/react-dom": "latest", "@types/react-router-dom": "latest", "@types/webpack-env": "latest", "@typescript-eslint/eslint-plugin": "latest", "@typescript-eslint/parser": "latest", "autoprefixer": "latest", "babel-loader": "latest", "clean-webpack-plugin": "latest", "copy-webpack-plugin": "latest", "cross-env": "latest", "css-loader": "latest", "css-minimizer-webpack-plugin": "latest", "csv-loader": "latest", "eslint": "latest", "eslint-plugin-jsx-a11y": "latest", "eslint-plugin-react": "latest", "eslint-webpack-plugin": "latest", "file-loader": "latest", "html-loader": "latest", "html-webpack-plugin": "latest", "imagemin": "latest", "imagemin-webp": "latest", "imagemin-webp-webpack-plugin": "latest", "mini-css-extract-plugin": "latest", "node-sass": "latest", "postcss": "latest", "postcss-loader": "latest", "sass": "latest", "sass-loader": "latest", "style-loader": "latest", "terser-webpack-plugin": "latest", "thread-loader": "latest", "ts-loader": "latest", "typescript": "^5.0.4", "webpack": "latest", "webpack-bundle-analyzer": "latest", "webpack-cli": "latest", "webpack-dev-middleware": "latest", "webpack-dev-server": "latest", "webpack-merge": "latest", "webpackbar": "latest", "xml-loader": "latest" }, "dependencies": { "react": "latest", "react-dom": "latest", "react-redux": "latest", "react-router-dom": "latest", "redux": "latest", "redux-devtools-extension": "latest", "redux-thunk": "latest" } }
Webpack配置文件
webpack.config.js
const { merge } = require("webpack-merge"), common = require("./webpack/webpack.common.js"), envs = { development: "dev", production: "prod" }, env = envs[process.env.NODE_ENV || "development"], envConfig = require(`./webpack/webpack.${env}.js`), dirname = __dirname module.exports = env => merge(common(env, dirname), envConfig(dirname))
webpack.common.js
const path = require("path"), os = require("os"), HTMLWebpackPlugin = require("html-webpack-plugin"), CopyWebpackPlugin = require("copy-webpack-plugin"), MiniCssExtractPlugin = require("mini-css-extract-plugin"), { CleanWebpackPlugin } = require("clean-webpack-plugin") module.exports = (env, dirname) => { const isDev = env === "development", isProd = env === "production", filename = ext => isDev ? `[name]${ext}` : `[name].[contenthash]${ext}`, cssLoader = loader => { const config = [ isDev ? "style-loader" : { loader: MiniCssExtractPlugin.loader, options: { publicPath: "../" }, }, { loader: "css-loader", options: { esModule: true, importLoaders: 1, modules: { mode: "icss" } } }, { loader: "postcss-loader", options: { postcssOptions: { plugins: isProd ? [ ["autoprefixer"] ] : [] } } } ] if (loader) config.push(loader) return config }, jsLoader = loader => { const config = [ { loader: "thread-loader", options: { poolTimeout: 2000, workers: os.cpus().length - 1 } }, { loader: "babel-loader", options: { presets: isProd ? ["@babel/preset-env", "@babel/preset-react"] : [] } } ] if (loader) config.push(loader) return config }, plugins = () => [ new HTMLWebpackPlugin({ template: "./index.html", inject: "body", minify: { collapseWhitespace: isProd } }), new CleanWebpackPlugin(), new CopyWebpackPlugin({ patterns: [ { from: path.resolve(dirname, "src/favicon.ico"), to: path.resolve(dirname, "dist") }, { from: path.resolve(dirname, ".gitignore"), to: path.resolve(dirname, "dist") } ] }), new MiniCssExtractPlugin({ filename: `css/${filename(".css")}` }) ] return ({ context: path.resolve(dirname, "src"), cache: true, entry: { main: ["@babel/polyfill", "./ts/index.ts"] }, output: { filename: `${filename(".js")}`, path: path.resolve(dirname, "dist"), assetModuleFilename: "[path][name][ext]", clean: true }, resolve: { extensions: [".js", ".ts", ".jsx", ".tsx", ".json"], alias: { "@": path.resolve(dirname, "src") } }, optimization: { minimize: true, runtimeChunk: 'single', splitChunks: { chunks: 'all', maxInitialRequests: Infinity, minSize: 0, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name(module) { const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/) ?? 'package'; return `npm.${packageName[1].replace('@', '')}`; } } } } }, plugins: plugins(), module: { rules: [ { test: /\.m?jsx?$/, exclude: /node_modules/, use: jsLoader() }, { test: /\.tsx?$/, exclude: /node_modules/, use: jsLoader({ loader: "ts-loader", options: { projectReferences: true, happyPackMode: true, transpileOnly: true } }) }, { test: /\.css$/, use: cssLoader() }, { test: /\.s[ac]ss$/, use: cssLoader("sass-loader") }, { test: /\.html$/, include: path.resolve(dirname, 'src/html/'), use: "html-loader" }, { test: /\.(ico|png|jpg|jpeg|svg|gif|mp4|webp|webm)$/, type: "asset/resource", generator: { filename: `./img/${filename("[ext]")}` }, }, { test: /\.(ttf|woff|woff2|otf|eot)$/, type: "asset/inline", generator: { filename: `./fonts/${filename("[ext]")}` } }, { test: /\.xml$/, use: ["xml-loader"] }, { test: /\.csv$/, use: ["csv-loader"] } ] } }) }
webpack.dev.js
const path = require("path"), ESLintWebpackPlugin = require("eslint-webpack-plugin"), WebpackBar = require("webpackbar"), { HotModuleReplacementPlugin } = require("webpack") module.exports = (dirname) => ({ mode: "development", target: "web", devtool: "eval-source-map", devServer: { compress: true, port: 3000, open: true, watchFiles: path.join(dirname, "/src"), historyApiFallback: true, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "*", "Access-Control-Allow-Headers": "*", }, client: { overlay: false } }, optimization: { usedExports: true }, plugins: [ new HotModuleReplacementPlugin(), new ESLintWebpackPlugin({ extensions: ["js", "ts", "jsx", "tsx"], failOnError: false }), new WebpackBar() ] })
内容的提问来源于stack exchange,提问作者Паша Макаренко
相关产品推荐
相关产品推荐

