Para parchar un plugin de Capacitor, edita los archivos del plugin en node_modulesguarda el cambio como una diferencia con bun patch --commit (o patch-package en npm y Yarn, pnpm patch-commit en pnpm), haz un commit del archivo generado en patches/entonces ejecuta bunx cap sync de modo que los proyectos nativos lo capturen. El administrador de paquetes reaplica la parche en cada instalación, para tu equipo y en CI.
Patching es la mejor opción cuando un plugin tiene un pequeño bug, una restricción de versión que bloquea tu compilación, o una corrección upstream que se ha fusionado pero no se ha lanzado. Este guía cubre el flujo de trabajo para cada administrador de paquetes, cómo las parches nativos llegan a Xcode y Gradle, y cuándo un fork o una PR upstream es la mejor opción.
¿Por qué la parcheado funciona para el plugin nativo code
Un plugin Capacitor es un paquete npm con tres partes: JavaScript en dist/Android code en android/y iOS code en ios/ y un podspec y/o Package.swift. Capacitor compila las partes nativas directamente desde node_modules:
- Android:
android/capacitor.settings.gradleincluye cada plugin’sandroidcarpeta desdenode_modules. - iOS con CocoaPods: el archivo Podfile referencia cada plugin con
:path => '../../node_modules/...'. - iOS con SPM:
CapApp-SPM/Package.swiftse refiere a cada plugin mediante ruta local ennode_modules.
Entonces un cambio a node_modules/@scope/plugin/ios/Sources/... termina en tu binario de aplicación después de cap sync y una reconstrucción. No hay nada que publicar.
Antes de parchear
- Verifica si hay una versión de lanzamiento. Mira el registro de cambios del plugin y abre PRs. Actualizar es mejor que parchear.
- Lee el licencia. MIT y Apache-2.0 permiten modificaciones privadas. Las licencias de copyleft como GPL o MPL-2.0 pueden requerir que pubiques el código fuente modificado cuando distribuyas la aplicación. Verifica antes de enviar.
- Escribe por qué. Coloca la URL del problema o una razón de una línea en tu mensaje de commit. Seis meses después nadie recuerda por qué
patches/tiene un archivo en él.
Parchear con Bun
Bun tiene parches integrados. No necesita un paquete adicional, ni postinstall un 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
Paso 1 hace que Bun te proporcione una copia privada del paquete en node_modulesAsí, las ediciones no afectan el caché global de Bun. El paso 3 escribe una diferencia y la registra en package.json:
{
"patchedDependencies": {
"@capacitor/haptics@8.0.2": "patches/@capacitor%2Fhaptics@8.0.2.patch"
}
}
Commit ambos package.json Comite ambos patches/ carpeta. Cada bun installcarpeta. Cada bun install --frozen-lockfile archivo, incluyendo
en CI, aplica el parche. El archivo contiene la versión exacta. Si aumentas la versión del plugin, Bun ya no coincide con el parche, por lo que debes recrearlo para la nueva versión o eliminarlo si la corrección se envió.
Parchear con npm o Yarn: patch-package
npm install --save-dev patch-package
Agregar un postinstall scripto para parches que se aplican después de cada instalación:
{
"scripts": {
"postinstall": "patch-package"
}
}
Entonces, edita los archivos en node_modules y genera el parche:
npx patch-package @capacitor/haptics
Esto escribe patches/@capacitor+haptics+8.0.2.patch. Cométalo. Si el parche deja de aplicarse después de una actualización, patch-package falla la instalación con un mensaje claro.
Yarn Berry tiene su propio yarn patch <pkg> / yarn patch-commit -s <path> flujo que almacena el parche en el resolutions campo.
Parchear con pnpm
pnpm patch @capacitor/haptics
# edit the temporary folder pnpm prints
pnpm patch-commit <path-printed-above>
registra pnpm la parche bajo patchedDependencies y la aplica al instalar.
Ejemplo: corregir un error de compilación nativa en un plugin
Un caso común: su aplicación utiliza AGP 9, y un plugin más antiguo android/build.gradle todavía referencia proguard-android.txt, que AGP 9 rechaza. No puede esperar a una versión.
bun patch some-capacitor-plugin
Editar 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'
}
}
Guardar y sincronizar:
bun patch --commit node_modules/some-capacitor-plugin
bunx cap sync android
cd android && ./gradlew assembleDebug
La información completa sobre este error se encuentra en solucione errores de compilación del plugin Capacitor con AGP 9.
Ejemplo: relajar una restricción de dependencia de 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'
For las aplicaciones de SPM, la misma restricción vive en el plugin’s 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")
Entonces:
bunx cap sync ios
Con CocoaPods, puede necesitar cd ios/App && pod update FirebaseMessaging una vez, porque Podfile.lock aún mantiene la versión antigua. Con SPM, utilice Archivo > Paquetes > Resolver versiones de paquetes en Xcode.
Patchear el Capacitor núcleo mismo
A veces el bug está en @capacitor/android, @capacitor/ios o el CLI, y la solución se encuentra en una solicitud de extracción de upstream. Puede parchar esos paquetes de la misma manera, pero cada equipo termina manteniendo las mismas diferencias.
Capgo publica @capgo/capacitor-patch para esto. Es un paquete de solo hooks con un catálogo de parches pequeños, versionados, que enlazan hacia atrás a sus PRs de upstream. No hace nada hasta que opte por:
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;
Las actualizaciones de paquetes se ejecutan antes cap sync y cap update, and native project patches run after. bunx capgo-capacitor-patch doctor realiza una prueba seca. strict: true, falla la sincronización cuando una actualización seleccionada ya no se aplica, lo que te indica que se ha vuelto obsoleta debido a una actualización. plugin docs los documentos del plugin
para obtener la lista completa de opciones.
| Situation | Situación |
|---|---|
| Corrija ya líneas, ya fusionada en la rama principal | Unas pocas líneas, solución ya fusionada upstream |
| Restricción de versión demasiado estricta | Patch, abrir un problema en la fuente |
| Bugs sin solución de la fuente aún | Patch y enviar un PR con el mismo diff |
| Nueva característica o refactorización grande | Fork, publicar bajo tu ámbito |
| Plugin abandonado | Fork, o cambiar a un plugin mantenido |
Forking bien
Si forks, publicarlo para que las instalaciones sigan siendo reproducibles:
# in the fork, rename to your scope in package.json: "@acme/capacitor-foo"
bun run build
bun publish --access restricted
Instalar desde una URL de Git también funciona, pero el carpeta del plugin dist/ debe existir en esa rama o ser construido por un prepare script, y no todos los administradores de paquetes ejecutan scripts de ciclo de dependencias por defecto. Un paquete publicado evita eso.
Recuerde que el nombre npm cambia el nombre del módulo nativo que CLI genera para SPM (@acme/capacitor-foo se convierte en AcmeCapacitorFooactualice el fork de Package.swift migrar un plugin __CAPGO_KEEP_0__ a SPM migrar un Capacitor plugin a SPM.
. Es posible que ya haya un plugin mantenido que lo cubra. directorio del plugin CapgoHay ya un plugin mantenible que cubre ese tema.
Upstreaming
The goal is to delete your patch. Open an issue with a minimal repro, your Capacitor and plugin versions, and the patch diff. Then open a PR. Maintainers merge small, tested fixes much faster than issue reports alone.
actualizaciones en vivo
Su paquete de web incluye el código JavaScript del plugin dist/Con lo cual, una actualización para el lado JS se envía con la próxima compilación web. Capgo actualizaciones en vivo que llega a los usuarios sin una versión de tienda.
Las actualizaciones nativas son diferentes. Los cambios en Swift, Kotlin, Java, Gradle, podspec o Package.swift solo tienen efecto en una nueva compilación nativa enviada a las tiendas. No envíe un paquete de web que dependa de una actualización nativa a usuarios que aún ejecutan la versión antigua. Capgo comprueba la compatibilidad compara las versiones del plugin nativo entre un paquete y un canal para detectar esto.
Solución de problemas
El parche no se aplica en CI. Asegúrese de que patches/ esté comprometido y no ignorado. Para patch-package, compruebe que CI no utiliza --ignore-scripts, que omite postinstall. Para Bun, comprueba patchedDependencies está en el archivo comitido package.json.
Mi cambio nativo no tiene efecto. Editaste el archivo pero no volviste a compilar. Ejecuta bunx cap sync, luego limpia: en Xcode Producto > Limpia carpeta de compilación, en Android ./gradlew clean. Con SPM, también resetea las cachés de paquetes.
bun patch --commit dice que no hay cambios. Editaste un archivo que no forma parte del paquete (por ejemplo, una copia levantada en otra carpeta). Edita la ruta Bun impresa en el paso 1.
La corrección falla después de actualizar el plugin. Verifique si la corrección está en la nueva versión. Si no, vuelva a aplicar la parche contra la nueva versión.
El plugin se compila, pero la aplicación se cae en esa característica. Los parches saltan la suite de pruebas del plugin. Pruebe el camino parcheado en un dispositivo real en ambas plataformas. El Guía de depuración de iOS Capacitor y Guía de depuración de Android explican cómo leer registros nativos.