Azure DevOps中React Native Android构建布局文件路径错误排查
错误信息
ERROR: /Users/runner/work/1/s/apps/primary-app/node_modules/my-react-library/android/src/main/res/layout/my_layout.xml: Resource and asset merger: Layout file /Users/runner/work/1/s/node_modules/my-react-library/android/src/main/res/layout/my_layout.xml is not located in [/Users/runner/work/1/s/node_modules/my-react-library/android/src/main/res, /Users/runner/work/1/s/node_modules/my-react-library/android/src/debug/res]
java.lang.IllegalStateException: Layout file /Users/runner/work/1/s/node_modules/ream-react-library/android/src/main/res/layout/my_layout.xml is not located in [/Users/runner/work/1/s/node_modules/my-react-library/android/src/main/res, /Users/runner/work/1/s/node_modules/my-react-library/android/src/debug/res]
关键疑点:错误日志中存在依赖名称拼写不一致(ream-react-library vs my-react-library),需优先排查此问题。
已完成的排查操作
- 确认
my_layout.xml存在于预期路径 - 流水线中执行
cd android && ./gradlew clean清理构建缓存后重试 - 本地构建无异常,仅CI流水线出现错误
- 更新Gradle、React Native及相关依赖至最新版本
- 确认流水线Gradle配置与本地可构建环境一致
可能的原因及对应解决方案
1. 依赖名称拼写错误/缓存脏数据
错误日志中的拼写错误大概率是CI环境的npm缓存存在旧的错误依赖条目,或依赖安装过程中出现名称解析异常。
- 解决方案:在CI流水线中添加清理npm缓存的步骤,强制重新安装依赖:
npm cache clean --force rm -rf node_modules package-lock.json npm install
2. CI环境的符号链接导致路径解析异常
React Native依赖在CI环境中可能通过符号链接安装,Gradle对符号链接的路径解析逻辑与本地复制安装不同,导致资源路径匹配失败。
- 解决方案:在npm安装时禁用符号链接,修改CI的npm install命令为:
npm install --no-symlink
3. 文件系统大小写敏感性差异
本地macOS环境可能使用了不区分大小写的APFS容器,而Azure DevOps的macOS runner默认使用区分大小写的文件系统。若依赖包中的路径存在大小写不一致(如Res vs res),本地可正常解析,但CI会报错。
- 解决方案:检查
my-react-library的Android目录结构,确保资源目录严格为src/main/res(全小写),同时确认Gradle配置中引用的路径大小写一致。
4. Gradle资源路径未显式配置
部分自定义React Native库未在build.gradle中显式指定资源目录,Gradle自动解析时可能因CI环境的多项目嵌套结构(apps/primary-app/)出现路径匹配错误。
- 解决方案:在
my-react-library/android/build.gradle中显式配置资源路径:android { sourceSets { main { res.srcDirs = ['src/main/res'] // 若有debug资源,可添加:debug.res.srcDirs = ['src/debug/res'] } } }
5. 主项目settings.gradle路径配置不匹配
主项目(apps/primary-app/)的settings.gradle中对library的路径引用可能未适配CI的工作目录结构。
- 解决方案:检查并修正
settings.gradle中的library路径:
(注:路径需根据CI工作目录include ':my-react-library' project(':my-react-library').projectDir = new File(rootProject.projectDir, '../../node_modules/my-react-library/android')/Users/runner/work/1/s/与主项目的相对位置调整)
内容的提问来源于stack exchange,提问作者Gennaro Amendola

