React App Rewired集成Module Federation插件报错求助
问题排查:React App Rewired集成Module Federation时出现"Cannot read properties of undefined (reading 'includes')"错误
当前配置
1. config-overrides.js代码
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); module.exports = { webpack: function(config, env) { config.externals = function(context, request, callback) { if (/canvg|pdfmake/.test(request)) { return callback(null, "commonjs " + request); } callback(); }; config.plugins.push(new ModuleFederationPlugin({ name: "app_1", filename: "remoteEntry.js", remotes: { app_2: "app_2@http://localhost:8081/remoteEntry.js", }, })); return config; }, };
2. package.json配置
{ "name": "Sample_app", "version": "0.1.358", "dependencies": { "@amcharts/amcharts4": "^4.10.20", "@deck.gl/mesh-layers": "^8.6.8", "@emotion/react": "^11.7.1", "@material-ui/core": "^4.12.3", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.60", "@mui/icons-material": "^5.1.1", "@mui/material": "^5.1.1", "@mui/styled-engine-sc": "^5.1.0", "@mui/styles": "^5.1.1", "@reactour/tour": "^2.9.0", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.2.7", "@testing-library/user-event": "^12.1.10", "@wsp/map-gl": "^2.1.11", "@wsp/map-react": "^1.1.2", "axios": "^0.24.0", "classnames": "^2.3.1", "dayjs": "^1.10.7", "express": "^4.17.1", "ignore-styles": "^5.0.1", "jest-fetch-mock": "^3.0.3", "jsonwebtoken": "^8.5.1", "lodash": "^4.17.21", "lodash.debounce": "^4.0.8", "md5-file": "^5.0.0", "mui-datatables": "^4.0.0", "node": "^16.13.1", "react": "^17.0.2", "react-data-export": "^0.6.0", "react-dom": "^17.0.2", "react-redux": "^7.2.6", "react-router-dom": "5.2.0", "react-scripts": "4.0.3", "react-select": "^5.4.0", "redux": "^4.1.2", "redux-mock-store": "^1.5.4", "redux-saga": "^1.1.3", "styled-components": "^5.3.3", "web-vitals": "^1.0.1" }, "scripts": { "start:local": "react-app-rewired start", "start": "REACT_APP_ENV_HOST=$REACT_APP_ENV_HOST node --max-http-header-size 16384 build/server", "build": "REACT_APP_ENV_HOST=$REACT_APP_ENV_HOST react-app-rewired build && cp -R ./server/* ./build && npm run moveFiles", "test": "react-scripts test", "test:coverage": "react-scripts test --coverage --watchAll=false", "eject": "react-scripts eject", "moveFiles": "cd build && mkdir channelperformance && cp -r ./static ./channelperformance/static", "storybook": "start-storybook -p 6006 -s public", "build-storybook": "build-storybook -s public", "test:update": "react-scripts test -u" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ], "overrides": [ { "files": [ "**/*.stories.*" ], "rules": { "import/no-anonymous-default-export": "off" } } ] }, "jest": { "collectCoverageFrom": [ "src/**/*.{js,jsx}", "!/node_modules/", "!src/coverage/**", "!src/index.js", "!src/stories/**" ], "coveragePathIgnorePatterns": [ "/src/constants", "/src/routes", "/src/helper", "/src/reportWebVitals.js", "/src/components/Drilldown/DownloadMuiTable", "/src/components/Drilldown/ReactVirtualized", "/src/components/Drilldown/Common/ChannelBreakdown.js" ], "transformIgnorePatterns": [ "[/\\\\]node_modules[/\\\\](?!(@amcharts)\\/).+\\.js$" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "resolutions": { "babel-eslint": "^10.0.0" }, "devDependencies": { "@e2e-test-utils/ui-shield": "^3.0.3", "@e2e-test-utils/ui-shield-utilities": "^4.1.5-0", "@storybook/addon-actions": "^6.5.10", "@storybook/addon-essentials": "^6.5.10", "@storybook/addon-interactions": "^6.5.10", "@storybook/addon-links": "^6.5.10", "@storybook/builder-webpack4": "^6.5.10", "@storybook/manager-webpack4": "^6.5.10", "@storybook/node-logger": "^6.5.10", "@storybook/preset-create-react-app": "^3.2.0", "@storybook/react": "^6.5.10", "@storybook/testing-library": "^0.0.13", "@wojtekmaj/enzyme-adapter-react-17": "^0.6.6", "babel-jest-amcharts": "^0.0.2", "enzyme": "^3.11.0", "enzyme-to-json": "^3.4.4", "eslint": "^7.28.0", "prettier": "2.3.1", "react-app-rewired": "^2.2.1", "redux-devtools-extension": "^2.13.9" } }
错误信息
运行项目时抛出错误:Cannot read properties of undefined (reading 'includes')
排查建议
修复
config.externals覆盖问题
当前直接替换config.externals为自定义函数,但Create React App默认的externals可能是数组或对象,替换后导致Webpack内部逻辑调用includes时找不到对应属性。修改为合并原有配置:module.exports = { webpack: function(config, env) { // 保留原有externals配置 const originalExternals = config.externals; config.externals = function(context, request, callback) { if (/canvg|pdfmake/.test(request)) { return callback(null, "commonjs " + request); } // 调用原有externals逻辑 if (typeof originalExternals === 'function') { originalExternals(context, request, callback); } else { callback(); } }; config.plugins.push(new ModuleFederationPlugin({ name: "app_1", filename: "remoteEntry.js", remotes: { app_2: "app_2@http://localhost:8081/remoteEntry.js", }, })); return config; }, };检查Webpack版本兼容性
React Scripts 4.0.3对应Webpack 4.x,而Module Federation在Webpack 5中才正式稳定。直接引入webpack/lib/container/ModuleFederationPlugin可能存在版本不匹配问题,建议升级到React Scripts 5.x(对应Webpack 5),或使用适配Webpack 4的Module Federation相关插件。排查第三方库冲突
- 临时移除非核心依赖(如
amcharts、deck.gl),逐步排查是否是某个库导致加载异常。 - 检查私有库
@wsp/map-gl、@wsp/map-react是否存在依赖Webpack内部模块的情况。
- 临时移除非核心依赖(如
添加调试定位报错位置
在入口文件顶部添加全局错误捕获,获取详细报错栈:window.addEventListener('error', (e) => { console.error('Error stack:', e.error.stack); });
React App Rewired集成Module Federation示例(适配Webpack 5)
1. 升级依赖
npm install react-scripts@5.0.1 react-app-rewired@2.2.1 --save
2. config-overrides.js完整配置
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const deps = require('./package.json').dependencies; module.exports = { webpack: (config, env) => { // 合并externals逻辑 const originalExternals = config.externals; config.externals = typeof originalExternals === 'function' ? function(context, request, callback) { if (/canvg|pdfmake/.test(request)) { return callback(null, `commonjs ${request}`); } originalExternals(context, request, callback); } : originalExternals; // 配置Module Federation config.plugins.push( new ModuleFederationPlugin({ name: 'app_1', filename: 'remoteEntry.js', remotes: { app_2: 'app_2@http://localhost:8081/remoteEntry.js', }, shared: { ...deps, react: { singleton: true, requiredVersion: deps.react, }, 'react-dom': { singleton: true, requiredVersion: deps['react-dom'], }, 'react-router-dom': { singleton: true, requiredVersion: deps['react-router-dom'], }, }, }) ); // 修改入口适配Module Federation if (env === 'development') { config.entry = ['webpack-dev-server/client?http://localhost:3000', './src/index']; } return config; }, };
3. 调整入口文件结构
- 修改
src/index.js:import('./bootstrap'); - 创建
src/bootstrap.js:import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') ); reportWebVitals();
内容的提问来源于stack exchange,提问作者ProblemSolver
相关产品推荐
相关产品推荐

