앱 스토어 없이 수동 Capacitor 번들 업데이트
모바일 Capacitor 앱은 사소한 JS 코드나 설정 변경만으로도 스토어에 전체 릴리스를 해야 합니다. 네이티브 코드 변경이 없어도 Google Play, RuStore, AppGallery, App Store 승인에 며칠이 걸립니다. 자동화가 도움이 되지만, 심사는 불가피합니다.
해결책은 네이티브 부분을 다시 빌드하지 않고 dist (또는 build) 디렉토리 내용을 업데이트하는 것입니다. @capgo/capacitor-updater 플러그인은 수동 또는 자동 모드로 원격 번들 교체를 지원합니다.
스토어 정책 준수
모든 플랫폼에서 조건을 충족하면 JS 번들 업데이트가 허용됩니다:
- Google Play: 리소스 남용 정책을 위반하지 않는 한 인터프리터 코드(JS)가 허용됩니다.
- App Store: 다운로드된 코드가 앱 목적을 변경하지 않고, 코드 저장소를 만들지 않으며, WebView 보안을 우회하지 않습니다.
Capacitor 하이브리드 앱의 경우 이러한 조건이 자동으로 충족됩니다.
설치 및 설정
종속성 설치:
npm i @capgo/capacitor-updater compare-versions
capacitor.config.ts에 추가:
plugins: {
CapacitorUpdater: {
autoUpdate: false,
},
},
autoUpdate: false 모드는 수동 업데이트 관리를 활성화합니다.
React용 AppUpdateProvider 생성 (자신의 프레임워크에 맞게 조정):
const AppUpdateProvider: FC<PropsWithChildren> = ({ children }) => {
return children;
};
export default AppUpdateProvider;
업데이트 로직
프로바이더에서 앱 시작 후 처음 10초 이내에 CapacitorUpdater.notifyAppReady()를 호출하세요. 그렇지 않으면 오류가 발생합니다.
API(GitHub 또는 내부 서비스)를 통해 최신 릴리스 데이터를 가져옵니다. compare-versions를 사용해 버전을 비교합니다.
전체 useEffect 예시:
useEffect(() => {
if (appRelease === null) {
dispatch(getAppRelease({ type: ReleaseType.APP, last: true }));
} else {
const downloadBundle = async () => {
dispatch(setAppUpdating(true));
return CapacitorUpdater.download({
url: APP_BUNDLE_DOWNLOAD_LINK,
version: appRelease.version,
});
};
CapacitorUpdater.addListener('downloadComplete', async ({ bundle: downloadedBundle }) => {
try {
await CapacitorUpdater.set(downloadedBundle);
dispatch(setAppUpdating(false));
} catch (e) {
console.error(e);
dispatch(setAppUpdating(false));
}
});
if (compare(String(version), appRelease.version, '<')) downloadBundle();
return () => {
CapacitorUpdater.removeAllListeners();
App.removeAllListeners();
};
}
}, [appRelease]);
번들 준비
Capgo CLI를 엄격히 사용해 번들 아카이브 생성:
npx @capgo/cli bundle zip [appId] --name [myapp]
capacitor.config.ts의appId.- 빌드 전에
package.json의version업데이트. - ZIP를 HTTPS 서버(GitHub Releases 또는 자체 호스팅)에 업로드.
아카이브 링크는 CapacitorUpdater.download({ url, version })에 전달됩니다.
다운로드 후 downloadComplete가 CapacitorUpdater.set()을 트리거합니다 — 번들이 교체되고 앱이 재시작됩니다.
앱 통합
전체 프로바이더:
const AppUpdateProvider: FC<PropsWithChildren> = ({ children }) => {
CapacitorUpdater.notifyAppReady();
const dispatch = useAppDispatch();
const appRelease = useAppSelector(selectAppRelease);
// useEffect how vyshe
return children;
};
main.tsx에서 App 래핑:
root.render(
<Provider store={store({})}>
<AppUpdateProvider>
<App />
</AppUpdateProvider>
</Provider>
);
주요 포인트
- JS 번들에 대해서만 작동하며 네이티브 플러그인은 해당되지 않습니다.
- 번들은
npx @capgo/cli bundle zip를 통해 아카이빙해야 합니다 — 다른 방법은 잘못된 것입니다. - 앱 시작 후 처음 10초 이내에
notifyAppReady()호출이 필수입니다. - 버전 비교:
compare(currentVersion, newVersion, '<'). - 자체 호스팅 Capgo — 완전한 제어를 위한 대안.
— Editorial Team
아직 댓글이 없습니다.