Ręczne aktualizowanie bundli Capacitor bez sklepów z aplikacjami
Aplikacje mobilne na Capacitor wymagają pełnego wydania w sklepach nawet dla drobnych poprawek w kodzie JS lub specyfikacjach. Bez zmian w kodzie natywnym proces zatwierdzania w Google Play, RuStore, AppGallery i App Store trwa dniami. Automatyzacja pomaga, ale moderacja jest nieunikniona.
Rozwiązanie polega na aktualizacji zawartości katalogu dist (lub build) bez ponownego budowania części natywnej. Plugin @capgo/capacitor-updater umożliwia zdalną wymianę bundla w trybie ręcznym lub automatycznym.
Zgodność z zasadami sklepów
Aktualizacje bundli JS są dozwolone przez wszystkie platformy pod warunkiem spełnienia warunków:
- Google Play: interpretowalny kod (JS) jest dopuszczalny, o ile nie narusza zasad nadużywania zasobów.
- App Store: ładowany kod nie zmienia przeznaczenia aplikacji, nie tworzy sklepu z kodem i nie omija zabezpieczeń WebView.
Warunki te są spełniane automatycznie dla aplikacji hybrydowych na Capacitor.
Instalacja i konfiguracja
Zainstaluj zależności:
npm i @capgo/capacitor-updater compare-versions
W capacitor.config.ts dodaj:
plugins: {
CapacitorUpdater: {
autoUpdate: false,
},
},
Tryb autoUpdate: false włącza ręczne zarządzanie aktualizacjami.
Utwórz provider AppUpdateProvider dla React (dostosuj do frameworka):
const AppUpdateProvider: FC<PropsWithChildren> = ({ children }) => {
return children;
};
export default AppUpdateProvider;
Logika aktualizacji
W providerze wywołaj CapacitorUpdater.notifyAppReady() w ciągu pierwszych 10 sekund od uruchomienia — w przeciwnym razie wystąpi błąd.
Pobierz dane o najnowszym wydaniu przez API (GitHub lub własny serwis). Porównaj wersje za pomocą compare-versions.
Przykład pełnego 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]);
Przygotowanie bundla
Archiwum bundla utwórz ściśle za pomocą Capgo CLI:
npx @capgo/cli bundle zip [appId] --name [myapp]
appIdzcapacitor.config.ts.- Zaktualizuj
versionwpackage.jsonprzed budowaniem. - Wgraj ZIP na serwer HTTPS (GitHub Releases lub własny hosting).
Link do archiwum przekazuj w CapacitorUpdater.download({ url, version }).
Po pobraniu downloadComplete wywołuje CapacitorUpdater.set() — bundl jest zastępowany, aplikacja uruchamia się ponownie.
Integracja w aplikacji
Pełny provider:
const AppUpdateProvider: FC<PropsWithChildren> = ({ children }) => {
CapacitorUpdater.notifyAppReady();
const dispatch = useAppDispatch();
const appRelease = useAppSelector(selectAppRelease);
// useEffect jak wyżej
return children;
};
W main.tsx owiń App:
root.render(
<Provider store={store({})}>
<AppUpdateProvider>
<App />
</AppUpdateProvider>
</Provider>
);
Co ważne
- Aktualizacje działają tylko dla bundla JS, bez natywnych pluginów.
- Bundl archiwizuj za pomocą
npx @capgo/cli bundle zip— inne metody są nieprawidłowe. - Wywołanie
notifyAppReady()jest obowiązkowe w ciągu pierwszych 10 s od uruchomienia. - Porównanie wersji:
compare(currentVersion, newVersion, '<'). - Self-hosted Capgo — alternatywa dla pełnej kontroli.
— Editorial Team
Brak komentarzy.