pnpm monorepo架构下MFE无法在webpack中使用共享库
我们团队基于pnpm workspaces的monorepo架构,正在用Webpack Module Federation构建React微前端(MFE)应用。项目目录结构如下:
apps |---app1 |------ ..... |------ package.json |---app2 |------ ..... |------ package.json |---app3 |------ ..... |------ package.json packages |---package-1 |------ ..... |------ package.json |---package-2 |------ ..... |------ package.json configs ... ... package.json
其中apps目录存放所有可执行应用,packages目录存放各MFE复用的共享库(比如design-system、icons)。
当前遇到的问题:在apps中引用packages导出的模块时,构建阶段无报错,IDE也能正常跳转至模块定义,但运行应用时Webpack抛出错误。
1. 校验共享库的package.json配置
确保packages下的共享库正确配置入口字段,指向编译后的产物(或源码,若未预编译)。示例配置:
{ "name": "@your-org/package-1", "main": "./dist/index.js", "module": "./dist/index.esm.js", "exports": { ".": { "import": "./dist/index.esm.js", "require": "./dist/index.js" } }, "files": ["dist"] }
如果共享库未预编译,需在Webpack配置中添加babel-loader或ts-loader处理packages目录的源码。
2. 修正Module Federation的共享规则
在各MFE的Webpack配置中,将内部共享库加入shared配置,同时开启singleton避免多实例冲突:
// 示例:app1/webpack.config.js const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); module.exports = { plugins: [ new ModuleFederationPlugin({ name: 'app1', remotes: { // 其他远程应用配置 }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, '@your-org/package-1': { singleton: true, eager: true }, '@your-org/package-2': { singleton: true, eager: true } } }) ] };
注意:shared中的包名必须与packages目录下对应库的package.json里的name完全一致。
3. 调整pnpm的hoisting配置
pnpm默认的hoisting策略可能导致Webpack无法正确解析内部包,在根目录的.npmrc中添加:
# 允许hoisting内部共享包 public-hoist-pattern[]=@your-org/*
同时确保各apps的package.json中对内部包的依赖使用工作区协议:
{ "dependencies": { "@your-org/package-1": "workspace:*", "@your-org/package-2": "workspace:*" } }
4. 配置Webpack与TS的路径解析
在Webpack配置中添加别名,确保能正确定位内部包:
// webpack.config.js const path = require('path'); module.exports = { resolve: { alias: { '@your-org/package-1': path.resolve(__dirname, '../../packages/package-1'), '@your-org/package-2': path.resolve(__dirname, '../../packages/package-2') }, extensions: ['.js', '.jsx', '.ts', '.tsx'] } };
如果使用TypeScript,同步在tsconfig.json中配置paths:
{ "compilerOptions": { "paths": { "@your-org/package-1": ["../packages/package-1/src"], "@your-org/package-2": ["../packages/package-2/src"] } } }
5. 检查依赖版本一致性
执行pnpm ls查看各应用与共享库的依赖版本,尤其是React、ReactDOM这类核心库,Module Federation对版本一致性要求严格,需确保所有应用使用同一版本。
6. 清除缓存后重构
缓存可能引发异常,执行以下命令清理后重新构建:
pnpm store prune pnpm install pnpm run build --force
内容的提问来源于stack exchange,提问作者Bhardwaj Avasarala

