Saltare al contenuto principale

Come patchare un plugin di Capacitor (Bun, npm, pnpm)

How to patch a Capacitor plugin con bun patch, patch-package o pnpm patch, applicare le correzioni native iOS e Android, e decidere quando forkare o upstreamare.

Crediti dell'articolo

Martino Donadieu

Autore

Valeria

Recensore

Jordan

Curatore

Come patchare un plugin Capacitor (Bun, npm, pnpm)

To patch a Capacitor plugin, editare i file del plugin in node_modulessalvare il cambiamento come diff con bun patch --commit (o patch-package On npm e Yarn, pnpm patch-commit Sulla pnpm), commetta il file generato in patches/, quindi esegui bunx cap sync così che i progetti nativi lo rilevano. Il gestore di pacchetti applica nuovamente il patch con ogni installazione, per il tuo team e in CI.

La patching è il passo giusto da fare quando un plugin ha un piccolo bug, una restrizione di versione che blocca la tua build, o un fix upstream che è stato incorporato ma non rilasciato. Questa guida copre il workflow per ogni gestore di pacchetti, come i patch nativi raggiungono Xcode e Gradle, e quando una fork o un PR upstream è la scelta migliore.

Perché la patching funziona per il plugin nativo code

Un plugin Capacitor è un pacchetto npm con tre parti: JavaScript in dist/Android code in android/e iOS code in ios/ e un podspec e/o Package.swift. Capacitor compila le parti native direttamente da node_modules:

  • Android: android/capacitor.settings.gradle Includono ogni plugin’s android cartella da node_modules.
  • iOS con CocoaPods: il file Podfile fa riferimento a ogni plugin con :path => '../../node_modules/...'.
  • iOS con SPM: CapApp-SPM/Package.swift fa riferimento a ogni plugin con percorso locale in node_modules.

Quindi una modifica a node_modules/@scope/plugin/ios/Sources/... finisce nel tuo file binario dell'app dopo cap sync e una ricompilazione. Non è necessario pubblicare nulla.

Prima di patchare

  1. Controlla una release. Guarda il changelog del plugin e gli PR aperti. Aggiornare è meglio che patchare.
  2. Leggi la licenza. MIT e Apache-2.0 consentono modifiche private. Le licenze copyleft come GPL o MPL-2.0 possono richiedere di pubblicare il codice modificato quando si distribuisce l'app. Controlla prima di spedire.
  3. Scrivi perché. Inserisci l'URL del problema o una ragione di una riga nel messaggio di commit. Dopo sei mesi, nessuno ricorda più perché patches/ ha un file in esso.

Patching con Bun

Bun ha patching integrato. Nessun pacchetto aggiuntivo, nessun 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

Passo 1 fa che Bun ti dia una copia privata del pacchetto in node_modulesCosì le modifiche non toccano il cache globale di Bun. Il passo 3 scrive una diff e la registra in package.json:

{
  "patchedDependencies": {
    "@capacitor/haptics@8.0.2": "patches/@capacitor%2Fhaptics@8.0.2.patch"
  }
}

Committa entrambi package.json e il patches/ cartella. Ogni bun install, inclusi bun install --frozen-lockfile in CI, applica il patch.

La chiave contiene la versione esatta. Se aumenti la versione del plugin, Bun non corrisponde più al patch, quindi ricrea il nuovo o cancellalo se il fix è stato rilasciato.

Patching con npm o Yarn: patch-package

npm install --save-dev patch-package

Aggiungi un postinstall scripto così le patch si applicano dopo ogni installazione:

{
  "scripts": {
    "postinstall": "patch-package"
  }
}

Poi modifica i file in node_modules e generare il patch:

npx patch-package @capacitor/haptics

Questo scrive patches/@capacitor+haptics+8.0.2.patch. Committilo. Se il patch non si applica più dopo un aggiornamento, patch-package fallisce l'installazione con un messaggio chiaro.

Yarn Berry ha la sua yarn patch <pkg> / yarn patch-commit -s <path> flusso che memorizza il patch nel resolutions campo.

Patching con pnpm

pnpm patch @capacitor/haptics
# edit the temporary folder pnpm prints
pnpm patch-commit <path-printed-above>

pnpm registra il patch sotto patchedDependencies e lo applica all'installazione.

Esempio: correggere un errore di build nativo in un plugin

Un caso comune: la tua app utilizza AGP 9, e un plugin più vecchio android/build.gradle riferisce ancora proguard-android.txt, che AGP 9 rifiuta. Non puoi aspettare una versione.

bun patch some-capacitor-plugin

Modifica 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'
     }
 }

Salva e sincronizza:

bun patch --commit node_modules/some-capacitor-plugin
bunx cap sync android
cd android && ./gradlew assembleDebug

La descrizione completa di questo errore è in risolvi Capacitor errori di compilazione del plugin con AGP 9.

Esempio: rilassare una restrizione di dipendenza iOS

Due plugin fissano versioni diverse dello stesso SDK e CocoaPods non riesce a risolverle. Se hai verificato che il plugin funziona con la versione più recente di SDK, rilassa la sua podspec:

-  s.dependency 'FirebaseMessaging', '11.15.0'
+  s.dependency 'FirebaseMessaging', '>= 11.15.0', '< 13.0'

Per le app SPM, la stessa restrizione vive nel 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")

Poi:

bunx cap sync ios

Con CocoaPods potresti dover cd ios/App && pod update FirebaseMessaging una volta, perché Podfile.lock ancora tiene la versione vecchia. Con SPM, utilizza File > Pacchetti > Risolvi le versioni dei pacchetti in Xcode.

Patching Capacitor core stesso

Alcuni bug sono in @capacitor/android, @capacitor/ios o il CLI, e il fix è presente in una richiesta di pull upstream. Puoi patchare quei pacchetti nello stesso modo, ma ogni team finisce per mantenere le stesse differenze.

Capgo pubblica @capgo/capacitor-patch per questo. È un pacchetto con hook unico con un catalogo di piccoli, version-governati patch che collegano a loro PR upstream. Non fa nulla fino a quando non opti in:

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;

Pacchetti di patch eseguono prima cap sync e cap updatee native progetti vengono patchati in seguito. bunx capgo-capacitor-patch doctor , e i patch di progetto nativi eseguono dopo. strict: true, il sincronizzazione fallisce quando una patch selezionata non si applica più, il che ti dice quando un aggiornamento l'ha resa obsoleta. plugin docs documenti del plugin

per la lista completa delle opzioni disponibili.

Situazione Miglior opzione
Qualche riga, riparazione già integrata upstream Patch, rimuovi dopo la prossima release
Vincolo di versione troppo stretto Patch, apri un issue upstream
Bug senza soluzione upstream ancora Patch e invia un PR con lo stesso diff
Nuova funzionalità o grande refactor Fork, pubblica sotto il tuo scope
Plugin abbandonato Fork, o passa a un plugin mantenuto

Forkare bene

Se si forka, pubblicarlo in modo che le installazioni rimangano riproducibili:

# in the fork, rename to your scope in package.json: "@acme/capacitor-foo"
bun run build
bun publish --access restricted

Instalare da un URL Git funziona anche, ma il plugin's dist/ il folder deve esistere in quella branca o essere costruito da un prepare Ricordate che il nome __CAPGO_KEEP_0__ cambia il nome del modulo nativo che __CAPGO_KEEP_1__ genera per SPM (

Ricorda che il nome del npm cambia il nome del modulo nativo che il CLI genera per SPM ("@acme/capacitor-foo becomes AcmeCapacitorFooper corrispondere. I dettagli sono in Package.swift migrate un plugin __CAPGO_KEEP_0__ a SPM migrare un plugin Capacitor con SPM.

Prima di creare una fork di un plugin per una funzionalità mancante, controlla il directory del plugin Capgo. Potrebbe già esistere un plugin mantenuto che copre questo.

Upstreaming

L'obiettivo è cancellare il tuo patch. Apri un issue con un minimo di riproduzione, le tue Capacitor e le versioni del plugin, e la differenza del patch. Poi apri un PR. I mantenitori integrano facilmente le piccole correzioni testate molto più velocemente rispetto ai rapporti di issue soli.

Patch e aggiornamenti live

Il tuo pacchetto web include il JavaScript del plugin da dist/, quindi un patch al lato JS viene inviato con il prossimo build web. Con Capgo aggiornamenti live che raggiunge gli utenti senza una versione di store.

I patch nativi sono diversi. Le modifiche a Swift, Kotlin, Java, Gradle, podspec o Package.swift hanno effetto solo in un nuovo build nativo inviato ai negozi. Non invia un pacchetto web che dipende da un patch nativo agli utenti che ancora eseguono il vecchio binario. Capgo verifica la compatibilità compara le versioni dei plugin nativi tra un pacchetto e un canale per catturare questo.

Risolvere i problemi

La patch non viene applicata in CI. Assicurati di patches/ è stato commesso e non ignorato. Per patch-package, controlla che CI non utilizzi --ignore-scripts, che salta postinstallPer Bun, controlla patchedDependencies è presente nel commit package.json.

La mia modifica nativa non ha effetto. Hai modificato il file ma non hai ricostruito. Esegui bunx cap sync, poi pulisci: in Xcode Product > Pulisci cartella di costruzione, su Android ./gradlew cleanCon SPM, resetta anche le cache dei pacchetti.

bun patch --commit dice che non ci sono modifiche. Hai modificato un file che non fa parte del pacchetto (ad esempio una copia spostata in un'altra cartella). Modifica il percorso Bun stampato nel passo 1.

La patch fallisce dopo l'aggiornamento del plugin. Controlla se la correzione è presente nella nuova versione. Se non è così, ripeti la patch contro la nuova versione.

La patch funziona, ma l'app si blocca su quella funzionalità. Le patch ignorano il set di test del plugin. Testa il percorso patch sul dispositivo reale su entrambe le piattaforme. Capacitor guida di risoluzione dei problemi per iOS e Guida di risoluzione dei problemi per Android spiega come leggere i log nativi.

Aggiornamenti live per le app Capacitor

Quando un bug nel layer web è attivo, invia la correzione attraverso Capgo invece di aspettare giorni per l'approvazione della store. Gli utenti ricevono l'aggiornamento in background mentre le modifiche native rimangono nel normale percorso di revisione.

Ultimi articoli dal nostro Blog

Capgo ti offre le migliori informazioni che ti servono per creare un'app mobile davvero professionale.