Expo Monorepo构建失败:@react-native-firebase/analytics模块未找到
解决Monorepo中Expo EAS构建时@react-native-firebase/analytics无法解析的问题
问题背景
在Monorepo环境下使用React Native + Expo EAS,应用目录为clients/mobile/<react native app>,metro.config.js存放于mobile文件夹,配置如下:
const { getDefaultConfig } = require('expo/metro-config'); const path = require('path'); // Find the project and workspace directories const projectRoot = __dirname; // This can be replaced with `find-yarn-workspace-root` const monorepoRoot = path.resolve(projectRoot, '../..'); const config = getDefaultConfig(projectRoot); // 1. Watch all files within the monorepo config.watchFolders = [monorepoRoot]; // 2. Let Metro know where to resolve packages and in what order config.resolver.nodeModulesPaths = [ path.resolve(projectRoot, 'node_modules'), path.resolve(monorepoRoot, 'node_modules'), ]; module.exports = config;
搭配TypeScript使用时,构建阶段出现以下错误:
Error: Unable to resolve module @react-native-firebase/analytics from /home/expo/workingdir/build/node_modules/@react-native-firebase/crashlytics/lib/handlers.js: @react-native-firebase/analytics could not be found within the project or in these directories: ../../node_modules node_modules ../../node_modules 17 | 18 | import { isError, once } from '@react-native-firebase/app/lib/common'; > 19 | import { getAnalytics, logEvent } from '@react-native-firebase/analytics';
原因分析
- 依赖缺失或安装不完整:
@react-native-firebase/crashlytics依赖@react-native-firebase/analytics,但该包可能未在Monorepo根目录或移动端项目中安装,或者依赖缓存存在异常。 - Metro路径解析逻辑问题:当前Metro配置的
nodeModulesPaths虽然包含了根目录和项目目录的node_modules,但EAS构建环境下的路径解析规则可能与本地不一致,导致firebase相关包无法被正确定位。 - Monorepo依赖hoist问题:若使用yarn/npm workspaces,依赖提升机制可能导致firebase包未被正确关联到移动端项目。
解决方案
1. 确保依赖正确安装
- 在Monorepo根目录执行安装命令,确保所有关联包都被安装:
npm install @react-native-firebase/app @react-native-firebase/analytics @react-native-firebase/crashlytics # yarn用户执行 yarn add @react-native-firebase/app @react-native-firebase/analytics @react-native-firebase/crashlytics - 若使用workspaces,在移动端项目的
package.json中显式声明这些依赖,避免hoist导致的关联失效:"dependencies": { "@react-native-firebase/app": "^X.X.X", "@react-native-firebase/analytics": "^X.X.X", "@react-native-firebase/crashlytics": "^X.X.X" // 其他依赖项... }
2. 调整Metro配置,明确包解析路径
修改metro.config.js,添加extraNodeModules指定firebase包的具体路径,确保Metro能精准定位:
const { getDefaultConfig } = require('expo/metro-config'); const path = require('path'); const projectRoot = __dirname; const monorepoRoot = path.resolve(projectRoot, '../..'); const config = getDefaultConfig(projectRoot); config.watchFolders = [monorepoRoot]; config.resolver.nodeModulesPaths = [ path.resolve(projectRoot, 'node_modules'), path.resolve(monorepoRoot, 'node_modules'), ]; // 强制指定firebase相关包的解析路径 config.resolver.extraNodeModules = { '@react-native-firebase/app': path.resolve(monorepoRoot, 'node_modules/@react-native-firebase/app'), '@react-native-firebase/analytics': path.resolve(monorepoRoot, 'node_modules/@react-native-firebase/analytics'), '@react-native-firebase/crashlytics': path.resolve(monorepoRoot, 'node_modules/@react-native-firebase/crashlytics'), }; module.exports = config;
3. 清理缓存并重新构建
- 本地环境清理缓存:
npx expo start --clear rm -rf node_modules && npm install # yarn用户执行 yarn cache clean && rm -rf node_modules && yarn install - EAS远程构建清理缓存:触发构建时勾选控制台的"Clear cache"选项,或使用命令行:
eas build --clear-cache
4. 检查TypeScript配置
确保tsconfig.json的模块解析规则正确,必要时添加路径映射:
{ "compilerOptions": { "moduleResolution": "node", "baseUrl": ".", "paths": { "@react-native-firebase/*": ["node_modules/@react-native-firebase/*", "../../node_modules/@react-native-firebase/*"] } } }
内容的提问来源于stack exchange,提问作者sakib11
相关产品推荐
相关产品推荐

