메인 콘텐츠로 건너뛰기

How to Patch a Capacitor Plugin (Bun, npm, pnpm)

How to patch a Capacitor plugin with bun patch, patch-package or pnpm patch, apply native iOS and Android fixes, and decide when to fork or upstream.

Article Credits

마틴 도나디유

작가

발레리아

리뷰어

조던

편집자

Capacitor 플러그인을 Capacitor로 업데이트하는 방법 (Bun, npm, pnpm)

To patch a Capacitor plugin, edit the plugin’s files in node_modules, 변경 사항을 __CAPGO_KEEP_0__로 저장하세요. bun patch --commit (또는 patch-package on npm 및 Yarn, pnpm patch-commit pnpm)에서 생성된 파일을 커밋하세요. patches/그런 다음 bunx cap sync native 프로젝트가 이를 인식하도록 하세요. 패키지 매니저는 설치 시마다 패치를 재적용하여 팀과 CI에서 사용하도록 합니다.

작은 버그, 빌드에 걸리는 버전 제한, 또는 업스트림으로 병합된但 아직 릴리스되지 않은修정에 대한 패치가 필요할 때 패치하는 것이 올바른 선택입니다. 이 가이드에서는 각 패키지 매니저의 워크플로우, native 패치가 Xcode와 Gradle로 전달되는 방법, 그리고 포크 또는 업스트림 PR가 더 나은 선택인지 여부를 설명합니다.

native 플러그인 code에 대한 패치의 이유

Capacitor 플러그인은 npm 패키지로 구성되며 세 가지 부분으로 나뉩니다: JavaScript dist/Android code android/iOS code ios/ 그리고 podspec 및/또는 Package.swiftCapacitor은 native 부분을 직접 Android에서 컴파일합니다. node_modules:

  • Android: android/capacitor.settings.gradle iOS에서 CocoaPods를 사용하여 각 플러그인의 android 폴더를 node_modules.
  • iOS에서 SPM을 사용하여각 플러그인을 로컬 경로로 참조합니다. :path => '../../node_modules/...'.
  • 따라서 앱 바이너리에 변경 사항이 포함되어: CapApp-SPM/Package.swift 재빌드가 필요합니다. 배포할 필요가 없습니다. node_modules.

플러그인을 패치하기 전에 node_modules/@scope/plugin/ios/Sources/... 릴리스를 확인하세요. cap sync 플러그인의 변경 로그와 열린 PR를 확인하세요. 업그레이드가 패치보다 낫습니다.

업그레이드가 패치보다 낫습니다.

  1. 업데이트 확인 Look at the plugin’s changelog and open PRs.
  2. 라이선스 읽기. MIT와 Apache-2.0은 사설 수정을 허용하지만 GPL이나 MPL-2.0과 같은 Copyleft 라이선스는 앱을 배포할 때 수정된 소스를 공개해야 할 수 있습니다. 배포하기 전에 확인하세요.
  3. 왜 그런지 적어보세요. 수정 메시지에 이슈 URL 또는 한 줄의 이유를 적어보세요. 여섯 달 후에는 왜 그런지 기억하지 못합니다. patches/ __CAPGO_KEEP_0__에 파일이 있습니다.

Bun는 패치 기능이 내장되어 있습니다. 별도의 패키지나 스크립트가 필요하지 않습니다.

1단계에서는 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

Bun의 패치 기능을 사용하여 패치합니다. node_modulesBun의 글로벌 캐시를 건드리지 않도록 편집이 이루어집니다. 3단계는 차이(diff)를 작성하고 기록합니다. package.json:

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

1단계와 3단계를 모두 완료하세요. package.json 그리고 patches/ 폴더. 모든 bun install, CI에서 포함하여 bun install --frozen-lockfile 에 적용합니다.

키에는 정확한 버전이 포함되어 있습니다. 플러그인을 버전업하면 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> flow를 통해 patch를 resolutions field에 저장합니다.

pnpm으로 패치하기

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

pnpm은 patch를 patchedDependencies 밑에 기록하고 설치 시 적용합니다.

예시: 플러그인 내 네이티브 빌드 오류 수정

일반적인 경우: 앱이 AGP 9를 사용하고, 플러그인이 android/build.gradle AGP 9가 거부하는 proguard-android.txt를 참조하고 있습니다. 릴리스를 기다릴 수 없습니다.

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

이 오류에 대한 전체 배경은 AGP 9로 Capacitor 플러그인 빌드 오류를 고치려면 .

예시: iOS 의존성 제약을 완화하십시오

두 플러그인이 동일한 SDK의 다른 버전을 고정하고 CocoaPods가 그들을 해결할 수 없을 때 발생합니다. 만약 SDK의 새로운 버전으로 플러그인이 작동하는 것을 확인했다면, podspec을 완화하십시오:

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

SPM 앱의 경우, 제약은 플러그인의 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")

그렇다면:

bunx cap sync ios

CocoaPods의 경우 cd ios/App && pod update FirebaseMessaging 한 번만, Podfile.lock 아직도 이전 버전을 유지하고 있습니다. SPM의 경우, Xcode에서 파일 > 패키지 > 패키지 버전 해결 Xcode에서.

Patching Capacitor core itself

버그는 종종 @capacitor/android, @capacitor/ios 혹은 CLI 에서 발견되며, 수정은 상류 pull request 에서 발견된다. 그 경우에도 패키지를 동일한 방법으로 패치할 수 있지만, 모든 팀은 동일한 diff 를 유지해야 한다.

Capgo는 @capgo/capacitor-patch 를 발행한다. 그것은 hook-only 패키지로, 버전-게이트드 패치의 카탈로그를 가지고 있으며, 그 패치들은 상류 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 and cap updatecontext bunx capgo-capacitor-patch doctor , 그리고 원본 프로젝트 패치가 strict: true뒤에 실행된다. dry run을 한다. 와 함께, 선택한 패치가 더 이상 적용되지 않으면 sync가 실패한다. 그 경우 업그레이드가 그것을 무효화했다는 것을 알려준다.

를 참조하라. 그곳에서 전체 옵션 목록을 확인할 수 있다.

상황 최선의 선택
업스트림에서 이미 병합된 몇 줄의 수정 패치, 다음 릴리즈 후 삭제
버전 제약이 너무 엄격하다 패치, 업스트림에 이슈를 열어라
업스트림에서 아직 수정이 없는 버그 패치하고 PR에 동일한 diff를 보내라
새로운 기능이나 큰 리팩토링 포크, 자신의 범위에서 배포
플러그인은 이미 폐기되었다 포크하거나 유지 관리되는 플러그인으로 전환

포크 잘 함

포크한 경우 설치가 reproducible 하도록 공개하세요:

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

git URL로 설치하는 것도 가능하지만, 플러그인의 dist/ 폴더는 해당 branch에서 존재해야 하거나 CLI 명령어로 빌드되어야 합니다. prepare __CAPGO_KEEP_0__ 이름이 native module 이름을 __CAPGO_KEEP_1__가 SPM에서 생성하는 이름으로 바꾸므로, fork의

npm 이름이 변경되면 SPM이 생성하는 CLI의 네이티브 모듈 이름도 변경됩니다.@acme/capacitor-foo becomes AcmeCapacitorFoomissing feature를 위한 플러그인을 fork하기 전에, Package.swift __CAPGO_KEEP_0__ plugin directory migrate a Capacitor plugin to SPM.

becomes Capgo 플러그인 디렉토리. 이미 유지 관리되는 플러그인이 해당 기능을 커버하고 있을 수 있습니다.

업스트림

목표는 패치 삭제입니다. 최소한의 재현 가능한 문제, Capacitor 및 플러그인 버전, 패치 diff를 포함한 이슈를 열고, 다음으로 PR를 열어 주세요. 유지 관리자는 작은 테스트된 수정을 더 빠르게 병합합니다.

패치 및 라이브 업데이트

웹 번들에는 플러그인의 자바스크립트가 포함되어 있기 때문에, JS 측의 패치를 다음 웹 빌드로 함께 배포합니다. dist/__CAPGO_KEEP_0__ 라이브 업데이트 Capgo 라이브 업데이트 네이티브 패치는 다릅니다. 스위프트, 코틀린, 자바, 그레이들, podspec 또는

새로운 네이티브 빌드만 제출했을 때만 변경 사항이 적용됩니다. 여전히旧 버전의 바이너리를 실행하는 사용자에게 웹 번들을 푸시하지 마세요. __CAPGO_KEEP_0__의 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 번들 및 채널 사이의 네이티브 플러그인 버전을 비교하여 이 문제를 잡아내는 호환성 검사

문제 해결

CI에서 패치가 적용되지 않습니다. 정확히 확인하세요. patches/ patch-package에서 CI가 --ignore-scripts를 사용하지 않는지 확인하세요. postinstall. 플러그인을 업데이트하기 위해서는 Bun을 확인하세요. patchedDependencies 정확히 확인하세요. package.json.

patch-package에서 CI가 를 사용하지 않는지 확인하세요. bunx cap sync__CAPGO_KEEP_0__ 가 커밋된 My native 변경 사항이 효과가 없습니다. 파일을 편집했지만 다시 빌드하지 않았습니다. Run `npx cap sync`를 실행하고 Xcode에서 `Product > Clean Build Folder`를 클릭하세요. Android에서 `npx cap sync`를 실행하고 `clean`를 클릭하세요. ./gradlew clean. SPM으로 패키지 캐시도 초기화하세요.

bun patch --commit 변경 사항이 없다고 말합니다. 패키지에 포함되지 않은 파일을 편집했습니다 (예를 들어 다른 폴더에 있는 호이스팅된 복사본). 1단계에서 출력된 경로 Bun를 편집하세요.

플러그인 업그레이드 후 패치가 실패합니다. 수정 사항이 새로운 릴리즈에 포함되어 있는지 확인하세요. 그렇지 않다면 새로운 버전으로 패치를 다시 적용하세요.

플러그인이 빌드되지만 앱이 해당 기능에서 충돌합니다. 패치들은 플러그인의 테스트 스위트를 건너뜁니다. 실제 기기에서 patched 경로를 테스트하세요. iOS 및 Android両 플랫폼에서. Capacitor iOS 문제 해결 가이드 그리고 Android 문제 해결 가이드 native 로그를 읽는 방법에 대해 다룹니다.

실시간 업데이트: Capacitor 앱

웹层 버그가 실시간으로 실행 중일 때, 앱 스토어 승인 대기 없이 Capgo를 통해 패치를 배포하세요. 사용자는 배경에서 업데이트를 받으며 네이티브 변경 사항은 일반적인 검토 경로에 남아 있습니다.

최신 블로그

Capgo은 전문적인 모바일 앱을 만들기 위해 필요한 최고의洞察력을 제공합니다.