Cordova自动注入MSAL依赖致构建错误,能否用build-extras.gradle覆盖?
问题背景
我维护一个覆盖Android和iOS平台的Cordova MSAL插件,当Gradle版本≥8.2时,无论通过plugin.xml的<framework>标签还是build-extras.gradle引入com.microsoft.identity.client:msal:5.0.1,都会触发传递依赖错误:Could not resolve io.opentelemetry:opentelemetry-bom:1.18.0。该问题为MSAL已知问题,修复代码已合入dev分支但暂未发布至Maven仓库。
官方给出的临时修复方案是排除MSAL的opentelemetry依赖并手动引入所需组件,但将配置写入build-extras.gradle后发现,插件安装时会自动在生成的Android基础build.gradle中插入一行implementation "com.microsoft.identity.client:msal:5.0.1",导致排除规则失效。手动删除该行可正常构建,但无法在批量场景中推广。
可行解决方案
1. 在plugin.xml中直接配置带排除规则的MSAL依赖
这是最符合Cordova插件规范的方案,无需额外处理自动生成的代码。直接在plugin.xml的Android平台配置中添加带排除规则的MSAL依赖,并手动引入所需的opentelemetry组件:
<platform name="android"> <!-- 引入MSAL并排除opentelemetry传递依赖 --> <framework src="com.microsoft.identity.client:msal:5.0.1"> <param name="exclude" value="group: 'io.opentelemetry'" /> </framework> <!-- 手动添加所需的opentelemetry依赖 --> <framework src="io.opentelemetry:opentelemetry-api:1.18.0" /> <framework src="io.opentelemetry:opentelemetry-context:1.18.0" /> </platform>
配置后,Cordova自动生成的build.gradle中的MSAL依赖会自动带上exclude规则,不会出现未排除的重复依赖。
2. 使用Cordova钩子脚本移除自动插入的依赖行
编写一个Node.js钩子脚本,在构建前自动修改生成的Android build.gradle文件,删除自动插入的MSAL依赖行:
- 在插件目录下创建脚本文件
scripts/after_prepare/remove_msal_auto_dep.js:
const fs = require('fs'); const path = require('path'); module.exports = function(context) { // 定位到Android app模块的build.gradle文件 const buildGradlePath = path.join( context.opts.projectRoot, 'platforms', 'android', 'app', 'build.gradle' ); if (!fs.existsSync(buildGradlePath)) return; let content = fs.readFileSync(buildGradlePath, 'utf8'); // 匹配并移除自动插入的MSAL依赖行 content = content.replace(/^\s*implementation "com.microsoft.identity.client:msal:5.0.1"\s*$/gm, ''); fs.writeFileSync(buildGradlePath, content, 'utf8'); };
- 在plugin.xml中注册该钩子:
<platform name="android"> <hook type="after_prepare" src="scripts/after_prepare/remove_msal_auto_dep.js" /> </platform>
钩子会在cordova prepare执行后自动运行,清理多余的依赖行。
3. 使用Gradle依赖替换规则强制覆盖
在build-extras.gradle中添加依赖替换策略,强制所有MSAL依赖应用排除规则,即使插件自动插入了依赖行也会生效:
configurations.all { resolutionStrategy.dependencySubstitution { substitute module('com.microsoft.identity.client:msal:5.0.1') with module('com.microsoft.identity.client:msal:5.0.1') { exclude group: 'io.opentelemetry' } } } dependencies { implementation 'io.opentelemetry:opentelemetry-api:1.18.0' implementation 'io.opentelemetry:opentelemetry-context:1.18.0' }
这种方法通过Gradle的解析策略强制替换依赖,确保排除规则全局生效。
内容的提问来源于stack exchange,提问作者wrobins

