开发模式运行webpack-dev-server加载远程联邦模块时浏览器标签页冻结
环境依赖
- webpack: 5.73.0
- webpack-dev-server: 4.9.2
问题说明
该问题出现在通过webpack-dev-server运行、借助ModuleFederationPlugin消费微应用的宿主应用场景中:
- 宿主与远程微应用ExampleModule均通过webpack-dev-server本地启动时,从
localhost:3001加载模块运行完全正常 - 宿主通过webpack-dev-server运行,加载远程地址的生产构建版ExampleModule时,远程入口文件拉取完成后页面立即卡死无响应,浏览器控制台、服务端命令行日志均无任何报错输出,所有浏览器均可复现,测试环境为macOS Monterey
问题触发存在明确特征:
- 仅当宿主的webpack-dev-server以
development模式运行时触发,将运行模式切换为production即可恢复正常 - 直接托管宿主的静态构建产物时,无论构建时使用何种webpack模式,都不会出现该问题
目前该问题无法稳定复现:使用相同依赖版本、高度近似的webpack配置搭建隔离的React宿主+远程模块测试用例时,暂未复现上述异常,推测问题与非公开的业务代码逻辑相关,征集同类问题的排查、解决经验。
宿主配置示例
const path = require('path'); const { ModuleFederationPlugin } = require('webpack').container; const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: path.resolve(__dirname, "src/index.js"), mode: "development", // 修改为"production"模式即可正常运行 devServer: { port: 3000, client: { overlay: false, }, }, output: { path: path.resolve(__dirname, "./build"), publicPath: "/", filename: "[name].[contenthash].js", clean: true, }, module: { rules: [ { test: /\.jsx?$/, loader: "babel-loader", exclude: /node_modules/, options: { presets: ["@babel/preset-react"], }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: "Host", remotes: { ExampleModule: `ExampleModule@${ process.env.LOCAL_MODULE ? `http://localhost:3001/` : "https://example.com/examplemodule/" }remoteEntry.js`, }, shared: [ { react: { version: "16.13.0", singleton: true }, "react-dom": { version: "16.13.0", singleton: true }, }, ], }), new HtmlWebpackPlugin({ template: path.join(__dirname, "public/index.html"), }), ], };
远程模块配置示例
const path = require('path'); const { ModuleFederationPlugin } = require('webpack').container; const HtmlWebpackPlugin = require('html-webpack-plugin'); const PORT = 3001; module.exports = { entry: path.resolve(__dirname, "src/index.js"), mode: "development", // 静态托管构建产物时需设置为"production" devServer: { static: { directory: path.join(__dirname, "public") }, port: PORT, }, output: { path: path.resolve(__dirname, "./build"), publicPath: process.env.NODE_ENV === "development" ? `http://localhost:${PORT}/` : "https://example.com/examplemodule/", filename: "[name].[contenthash].js", clean: true, }, resolve: { extensions: [".js", ".jsx"], }, module: { rules: [ { test: /\.jsx?$/, loader: "babel-loader", exclude: /node_modules/, options: { presets: ["@babel/preset-react"], }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: "ExampleModule", library: { type: "var", name: "ExampleModule" }, filename: "remoteEntry.js", exposes: { "./ExampleModule": "./src/ExampleModule", }, shared: [ { react: { version: "16.13.0", singleton: true }, "react-dom": { version: "16.13.0", singleton: true }, }, ], }), new HtmlWebpackPlugin({ template: path.join(__dirname, "public/index.html"), }), ], };
内容的提问来源于stack exchange,提问作者s-gmr
相关产品推荐
相关产品推荐

