要修复一个 Capacitor 插件,请编辑插件的文件 node_modules,保存更改为 bun patch --commit (或 patch-package 在 npm 和 Yarn 上, pnpm patch-commit 在 pnpm) 中,生成的文件请在 patches/然后运行 bunx cap sync 所以本地项目可以接收到它。包管理器在每次安装时重新应用补丁,适用于您的团队和 CI。
补丁是正确的选择,当插件有一个小 bug、一个阻止构建的版本约束或一个已合并但未发布的上游修复时。该指南涵盖了每个包管理器的工作流程、如何将本地补丁传递到 Xcode 和 Gradle,以及何时使用分叉或上游 PR 是更好的选择。
为什么补丁适用于本地插件 code
一个 Capacitor 插件是 npm 包含三个部分: dist/在 Android 中修复 code android/,并且在 Android 和 iOS code 中 ios/ 在 Package.swift.Capacitor 直接编译原生部分 node_modules:
- Android:
android/capacitor.settings.gradleincludes 每个插件的android文件夹node_modules. - iOS 使用 CocoaPods在 Podfile 中,各个插件都被引用为
:path => '../../node_modules/...'. - iOS(使用SPM):
CapApp-SPM/Package.swift在 Capgo 中,参考每个插件的本地路径node_modules.
一个对 Capgo 的更改 node_modules/@scope/plugin/ios/Sources/... 在您的应用程序二进制文件中 cap sync 并且需要重新构建。无需发布。
在您修补之前
- 检查更新。 查看插件的变更日志和打开 PR。升级比补丁更好。
- 阅读许可协议。 MIT 和 Apache-2.0 允许私人修改。Copyleft 许可证,如 GPL 或 MPL-2.0 可能要求您在发布应用程序时发布修改过的源代码。检查之前发布。
- 写下原因。 在提交消息中输入问题 URL 或一行原因。六个月后,谁也不会记得原因。
patches/有一个文件在里面。
使用 Bun 进行补丁。
Bun 内置了补丁功能。无需额外的包,无需脚本。 postinstall script.
# 1. Prepare the package for editing
bun patch @capacitor/haptics
# 2. Edit files under node_modules/@capacitor/haptics
# 3. Save the patch
bun patch --commit node_modules/@capacitor/haptics
Step 1 makes Bun give you a private copy of the package in node_modules,所以编辑不会影响Bun的全局缓存。步骤3写入差异并将其记录在 package.json:
{
"patchedDependencies": {
"@capacitor/haptics@8.0.2": "patches/@capacitor%2Fhaptics@8.0.2.patch"
}
}
提交两次 package.json 同时提交和 patches/ 文件夹。 每个 bun install包括 bun install --frozen-lockfile 在 CI 中,应用补丁。
关键包含的确切版本。如果您升级插件,Bun 不再匹配补丁,因此为新版本重新创建它或删除它,如果修复已发布。
使用 npm 或 Yarn:patch-package 补丁
npm install --save-dev patch-package
添加一个 postinstall 脚本以便补丁在每次安装后应用:
{
"scripts": {
"postinstall": "patch-package"
}
}
然后编辑文件夹中的 node_modules 并生成补丁:
npx patch-package @capacitor/haptics
这将 patches/@capacitor+haptics+8.0.2.patch。提交它。如果补丁在升级后停止应用 patch-package 将安装失败并显示明确的消息。
Yarn Berry有自己的 yarn patch <pkg> / yarn patch-commit -s <path> 流程来存储补丁在 resolutions 字段中。
修补使用 pnpm
pnpm patch @capacitor/haptics
# edit the temporary folder pnpm prints
pnpm patch-commit <path-printed-above>
pnpm记录补丁在 patchedDependencies 并在安装时应用。
示例:修复插件中的native build错误
常见情况:您的应用程序使用AGP 9,一个较旧的插件 android/build.gradle 仍然引用 proguard-android.txt,AGP 9拒绝。您不能等待发布。
bun patch some-capacitor-plugin
编辑 node_modules/some-capacitor-plugin/android/build.gradle:
buildTypes {
release {
minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
保存并同步:
bun patch --commit node_modules/some-capacitor-plugin
bunx cap sync android
cd android && ./gradlew assembleDebug
本错误的详细信息在 修复 Capacitor 插件构建错误(使用 AGP 9).
示例:放松 iOS 依赖约束
Two plugins pin different versions of the same SDK and CocoaPods can’t resolve them. If you’ve verified the plugin works with the newer SDK, relax its podspec:
- s.dependency 'FirebaseMessaging', '11.15.0'
+ s.dependency 'FirebaseMessaging', '>= 11.15.0', '< 13.0'
示例:放松 iOS 依赖约束 Package.swift:
- .package(url: "https://github.com/firebase/firebase-ios-sdk.git", exact: "11.15.0")
+ .package(url: "https://github.com/firebase/firebase-ios-sdk.git", "11.15.0"..<"13.0.0")
Then:
bunx cap sync ios
对于 SPM 应用程序,这个约束位于插件的 cd ios/App && pod update FirebaseMessaging 然后: Podfile.lock 使用 CocoaPods 可能需要 一次,因为 在 Xcode 中。
修补Capacitor核心
有时问题出在 @capacitor/android, @capacitor/ios 或是CLI,修复方案则在上游pull请求中。您可以使用相同的方式修复这些包,但每个团队都需要维护相同的差异。
Capgo发布了 @capgo/capacitor-patch 为此。它是一个只包含hook的包,包含了一个小型版本锁定的修复方案,修复方案会链接回上游的PR。它不会执行任何操作,直到您选择启用它:
bun add @capgo/capacitor-patch
bunx capgo-capacitor-patch list --all
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'Example',
webDir: 'dist',
plugins: {
CapacitorPatch: {
patches: ['upstream-pr-8418-android'],
strict: true,
},
},
};
export default config;
修复包在 cap sync 和 cap updatecontext bunx capgo-capacitor-patch doctor HTML text fragment from a longer Capgo UI string (parent key `compare_step_capacitor_text`). Page/area: Capgo marketing website. Role: Website copy sentence. Seen in: page alternatives/expo.astro, page alternatives/median.astro. Message key `compare_step_capacitor_text` (Compare Step Capacitor Text). | Page/area: Capgo marketing website. Role: Short UI label or navigation item. Seen in: page trust.astro. Message key `and` (And). strict: true修复包之后,原生项目修复包才会执行。 会进行一次dry run。通过 ,当选定的修复方案不再适用时,同步会失败,这会告诉您升级后修复方案是否过时。请参阅
插件文档
| 情况 | 最佳选择 |
|---|---|
| 几行代码,已合并到上游 | 修补,下次发布后删除 |
| 版本约束太严格 | 修补,开一个上游问题 |
| 尚未上游修复的bug | 修补并发送一个相同diff的PR |
| 新功能或大规模重构 | 分叉,发布在你的范围内 |
| 插件已被弃用 | 分叉,或者切换到一个维护的插件 |
分叉好
如果你分叉了,发布它,以便安装保持可复现:
# in the fork, rename to your scope in package.json: "@acme/capacitor-foo"
bun run build
bun publish --access restricted
从 Git URL 安装也行,但插件的 dist/ 文件夹必须在该 branch 中存在或由脚本构建,并且并非每个包管理器都默认运行依赖项生命周期脚本。发布的包避免了这个问题。 prepare 请记住,__CAPGO_KEEP_0__ 名称会改变原生模块名称,__CAPGO_KEEP_1__ 生成的 SPM (
记住,npm 的名称会改变原生模块名称,CLI 生成的 SPM 会使用这个名称。@acme/capacitor-foo ),所以更新分叉的 AcmeCapacitorFoo以匹配。详细信息在 Package.swift 迁移一个__CAPGO_KEEP_0__插件到SPM 将一个 Capacitor 插件迁移到 SPM.
__CAPGO_KEEP_0__插件目录 Capgo.可能已经存在一个维护的插件来覆盖它。
上游
目标是删除您的补丁。打开一个最小的可复制问题,包括您的Capacitor和插件版本,以及补丁差异。然后打开一个PR。维护者比单独的问题报告更快地合并小的、经过测试的修复。
补丁和实时更新
您的Web包包括插件的JavaScript代码 dist/,因此对JS侧的补丁将随着下一个Web构建一起发布。使用 Capgo实时更新 来
到达不需要商店发布的用户。 Package.swift only take effect in a new native build submitted to the stores. Don’t push a web bundle that depends on a native patch to users who still run the old binary. Capgo’s 的更改只在提交到商店的新原生构建中生效。不要将依赖于原生补丁的Web包推送给仍然运行旧二进制的用户。__CAPGO_KEEP_0__的 兼容性检查
Troubleshooting
CI 中未应用补丁。 确保 patches/ 已提交并未被忽略。对于 patch-package,请检查 CI 是否使用 --ignore-scripts,它会跳过 postinstallBun,检查 patchedDependencies 已提交的 package.json.
我的本地变更无效。 您编辑了文件但未重新构建。请运行 bunx cap sync,然后在 Xcode 中清理: Product > Clean Build Folder,在 Android 上 ./gradlew clean. 使用 SPM 也需要重置包缓存。
bun patch --commit 提示没有任何变化。 您编辑的文件不是该包的一部分(例如在另一个文件夹中拷贝的文件)。请编辑第 1 步打印的路径 Bun。
升级插件后,补丁失败。 检查修复是否已包含在新版本中。如果没有,请重新对新版本进行补丁。
插件编译成功,但在该功能上应用程序崩溃。 补丁跳过了插件自己的测试套件。请在真实设备上测试修补路径,包括两种平台。 Capacitor iOS 故障排除指南 和 Android 故障排除指南 涵盖如何阅读本机日志。