如何通过yarn link关联react-native-builder-bob构建的模块并在Expo中正常使用?
解决 Expo 本地链接 react-native-builder-bob 库的问题
我之前也踩过类似的坑,用react-native-builder-bob创建的库本地链接到Expo项目时,经常遇到模块找不到、peer依赖缺失的问题,结合你提到的Expo多版本兼容的情况,给你整理几个关键解决方案:
1. 先搞定模块无法解析的核心问题
你遇到的Unable to resolve module错误,本质是Metro没找到库的编译文件,或者没正确识别链接的库,按下面步骤来:
- 先构建本地库:react-native-builder-bob生成的库默认需要编译后才能被Expo识别,先在库的目录执行:
如果你想实时修改代码自动编译,可以用bob的监听模式:yarn buildyarn watch - 修改Metro配置:只加
watchFolders不够,还要配置解析规则,编辑Expo项目的metro.config.js:const { getDefaultConfig } = require('@expo/metro-config'); const path = require('path'); const config = getDefaultConfig(__dirname); // 添加本地库的绝对路径到监听目录 config.watchFolders = [ ...config.watchFolders, '/Users/trajano/p/myorg-react-native-ui', // 替换成你的库实际路径 ]; // 让Metro同时读取项目和库的node_modules,解决peer依赖找不到的问题 config.resolver.nodeModulesPaths = [ path.resolve(__dirname, 'node_modules'), '/Users/trajano/p/myorg-react-native-ui/node_modules', ]; // Expo 45+ 需要开启这个配置来支持符号链接解析 if (parseInt(require('expo/package.json').version) >= 45) { config.resolver.unstable_enableSymlinks = true; } module.exports = config; - 清除缓存重启:Metro的缓存经常会导致奇怪的解析问题,执行:
expo start --clear
2. 解决Peer Dependencies 找不到的问题
因为你的库和Expo项目的devDependencies版本不同,直接用yarn link会导致依赖解析混乱,推荐两个靠谱方案:
- 方案一:用Yarn工作空间替代link:把库和Expo项目放到同一个工作空间下,Yarn会统一管理依赖,自动处理peer依赖冲突。
在根目录创建package.json:
然后在根目录执行{ "private": true, "workspaces": [ "myapp", // 你的Expo项目目录 "myorg-react-native-ui" // 你的库目录 ] }yarn install,之后Expo项目可以直接引用@myorg/react-native-ui,不需要再手动link,依赖也会自动正确解析。 - 方案二:手动指定依赖路径:如果不想用工作空间,确保库的
node_modules已经安装完成,并且在Metro配置中添加了库的node_modules路径(上面的配置已经包含这一步),这样Metro会优先从库的node_modules中查找它需要的peer依赖。
3. 兼容 Expo 44 和 Expo 45 的技巧
要同时兼容两个版本的Expo,核心是避免库的依赖和项目依赖冲突:
- 把Expo相关依赖移到peerDependencies:不要把
expo、expo-status-bar等放到库的devDependencies,而是放到peerDependencies,指定兼容的版本范围:
这样Expo项目会使用自身的依赖版本,不会和库的dev依赖产生冲突。"peerDependencies": { "expo": "^44.0.0 || ^45.0.0", "react-native": ">=0.64.0", "expo-status-bar": "^1.2.0 || ^1.3.0" } - 代码中做版本兼容判断:如果某些API在两个版本中有差异,可以动态判断Expo版本:
import { Constants } from 'expo'; const isExpo45OrHigher = Constants.expoVersion >= 45; // 示例:根据版本使用不同的API逻辑 <StatusBar style={isExpo45OrHigher ? 'light' : 'auto'} /> - 用多个测试项目分别验证:创建两个Expo测试项目,一个用44版本,一个用45版本,都通过工作空间链接到你的库,分别测试,避免来回切换依赖版本的麻烦。
内容的提问来源于stack exchange,提问作者Archimedes Trajano
相关产品推荐
相关产品推荐

