重构后MFE Webpack配置报错:Cannot read properties of undefined (reading 'call')
Module Federation 导入报错排查:Cannot read properties of undefined (reading 'call')
问题背景
重构配置目录与Webpack入口文件后,宿主应用(HOST)导入远程应用(Remote Application)时出现错误:Cannot read properties of undefined (reading 'call'),重构前宿主应用运行正常,疑问是否与嵌套的/src/目录有关。
重构前可用目录结构
- / - /remote - /bootstrap - /app - /index - /webpack.config.js - /host - /bootstrap - /app - /index - /webpack.config.js
重构后触发报错的目录结构
- / - /remote/src - /bootstrap - /app - /index - /host/src - /bootstrap - /app - /index - /configs - /webpack.remote.js - /webpack.host.js
未修改的核心文件
- index.ts
import './App.tsx'
- App.tsx(实际应用组件)
- 宿主导入:
import Box from 'mfe/Box' - 远程导出:
export Box()
- 宿主导入:
- Bootstrap.tsx(独立挂载远程MFE用)
- 代码:
import './App',并将App挂载到DOM
- 代码:
Webpack配置仅修改的路径属性
- entry:从
./src/App.tsx改为./{folder}/src/App.tsx - HtmlWebPackPlugin.template:从
/src/index.html改为/{folder}/src/index.html - 远程MFE的exposes配置:
// 原配置 exposes: { "./App": "./src/index.ts" }, // 修改后 exposes: { "./App": "./remote/src/index.ts" },
重构后的完整Webpack配置
宿主配置(webpack.host.js)
const HtmlWebPackPlugin = require("html-webpack-plugin"); const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); const deps = require("./host/package.json").dependencies; module.exports = { mode: "development", entry: './host/src/App.tsx', output: { publicPath: "http://localhost:5000/", }, resolve: { extensions: ["*", ".tsx", ".ts", ".jsx", ".js", ".json"], }, devServer: { port: 5000, historyApiFallback: true, }, module: { rules: [ { test: /\.m?js/, type: "javascript/auto", resolve: { fullySpecified: false, }, }, { test: /\.(css|s[ac]ss)$/i, use: ["style-loader", "css-loader", "postcss-loader"], }, { test: /\.(ts|tsx|js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: "host", remotes: { 'module': "remote@http://localhost:5001/remoteEntry.js" }, exposes: {}, }), new HtmlWebPackPlugin({ template: "./host/src/index.html", }), ], };
远程配置(webpack.remote.js)
const HtmlWebPackPlugin = require("html-webpack-plugin"); const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); const deps = require("./remote/package.json").dependencies; module.exports = { mode: "development", entry: "./remote/src/Bootstrap.tsx", output: { publicPath: "http://localhost:5001/", }, resolve: { extensions: [".tsx", ".ts", ".jsx", ".js", ".json"], }, devServer: { port: 5001, historyApiFallback: true, }, module: { rules: [ { test: /\.m?js/, type: "javascript/auto", resolve: { fullySpecified: false, }, }, { test: /\.(css|s[ac]ss)$/i, use: ["style-loader", "css-loader", "postcss-loader"], }, { test: /\.(ts|tsx|js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: "remote", filename: "remoteEntry.js", exposes: { "./App": "./remote/src/index.ts" }, shared: { ...deps, react: { singleton: true, requiredVersion: deps.react, }, "react-dom": { singleton: true, requiredVersion: deps["react-dom"], }, }, }), new HtmlWebPackPlugin({ template: "./remote/src/index.html", }), ], };
报错原因分析与解决方案
这个错误和嵌套/src/目录本身无关,核心问题出在路径解析不匹配和Module Federation的导入映射错误,按以下步骤修复即可:
1. 统一宿主远程模块别名
宿主配置中remotes的别名是'module',但实际导入用的是import Box from 'mfe/Box',别名完全不一致导致Webpack无法定位远程模块。
修复:
修改宿主的remotes配置与导入别名一致:
remotes: { 'mfe': "remote@http://localhost:5001/remoteEntry.js" },
2. 明确远程配置的上下文路径
远程配置文件位于/configs/目录,Webpack默认以配置文件所在目录为解析上下文,可手动指定项目根目录为上下文,避免路径解析歧义:
const path = require('path'); module.exports = { context: path.resolve(__dirname, '../'), // 添加此行指定根目录 // 其他原有配置... }
3. 调整宿主入口加载顺序
Module Federation要求先加载remoteEntry.js再加载应用代码,直接将entry设为App.tsx可能导致加载顺序错误。
修复:
- 在
host/src/下创建bootstrap.tsx:
import './App.tsx';
- 修改宿主entry为:
entry: './host/src/bootstrap.tsx',
4. 验证远程模块导出方式
确保远程模块的导出与宿主导入方式匹配:
- 若宿主用
import Box from 'mfe/Box',远程需默认导出:
// remote/src/index.ts import { Box } from './App.tsx'; export default Box;
- 若宿主用
import { Box } from 'mfe/Box',远程用具名导出:
// remote/src/index.ts import { Box } from './App.tsx'; export { Box };
总结
按上述顺序修复后,即可解决Cannot read properties of undefined (reading 'call')错误,核心是保证模块映射、路径解析、加载顺序和导出导入方式的一致性。
内容的提问来源于stack exchange,提问作者devric
相关产品推荐
相关产品推荐

