Retour à l'accueil

Mise à jour manuelle des bundles Capacitor sans stores

L'article décrit l'intégration manuelle de @capgo/capacitor-updater pour les mises à jour OTA des bundles JS dans les apps Capacitor. Exemples de code du provider fournis, préparation des archives via CLI, vérification de la conformité aux règles des stores. Adapté aux développeurs middle/senior.

Capacitor : mises à jour de bundles contournant les approbations des stores
Advertisement 728x90

Mises à jour manuelles des bundles Capacitor sans les stores d'applications

Les applications mobiles Capacitor nécessitent une publication complète sur les stores même pour de simples ajustements de code JS ou de configuration. Sans modifications de code natif, l'approbation sur Google Play, RuStore, AppGallery et App Store prend des jours. L'automatisation aide, mais la modération est inévitable.

La solution consiste à mettre à jour le contenu du répertoire dist (ou build) sans reconstruire la partie native. Le plugin @capgo/capacitor-updater permet le remplacement des bundles à distance en mode manuel ou automatique.

Conformité aux politiques des stores

Les mises à jour de bundles JS sont autorisées par toutes les plateformes si les conditions sont remplies :

Google AdInline article slot
  • Google Play : Le code interprété (JS) est autorisé tant qu'il ne viole pas les politiques d'abus de ressources.
  • App Store : Le code téléchargé ne change pas l'objectif de l'application, ne crée pas un magasin de code et ne contourne pas la sécurité WebView.

Ces conditions sont automatiquement remplies pour les applications hybrides Capacitor.

Installation et configuration

Installez les dépendances :

npm i @capgo/capacitor-updater compare-versions

Dans capacitor.config.ts, ajoutez :

Google AdInline article slot
plugins: {
  CapacitorUpdater: {
    autoUpdate: false,
  },
},

Le mode autoUpdate: false active la gestion manuelle des mises à jour.

Créez un AppUpdateProvider pour React (adaptez à votre framework) :

const AppUpdateProvider: FC<PropsWithChildren> = ({ children }) => {
  return children;
};

export default AppUpdateProvider;

Logique de mise à jour

Dans le provider, appelez CapacitorUpdater.notifyAppReady() dans les 10 premières secondes de lancement — sinon, une erreur se produit.

Google AdInline article slot

Récupérez les données de la dernière release via API (GitHub ou service interne). Comparez les versions en utilisant compare-versions.

Exemple d'un useEffect complet :

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]);

Préparation du bundle

Créez l'archive du bundle strictement en utilisant Capgo CLI :

npx @capgo/cli bundle zip [appId] --name [myapp]
  • appId issu de capacitor.config.ts.
  • Mettez à jour version dans package.json avant la construction.
  • Téléversez le ZIP sur un serveur HTTPS (GitHub Releases ou votre propre hébergement).

Le lien de l'archive est passé à CapacitorUpdater.download({ url, version }).

Après téléchargement, downloadComplete déclenche CapacitorUpdater.set() — le bundle est remplacé et l'application redémarre.

Intégration dans l'application

Provider complet :

const AppUpdateProvider: FC<PropsWithChildren> = ({ children }) => {
  CapacitorUpdater.notifyAppReady();
  const dispatch = useAppDispatch();
  const appRelease = useAppSelector(selectAppRelease);

  // useEffect comme ci-dessus

  return children;
};

Dans main.tsx, enveloppez App :

root.render(
  <Provider store={store({})}>
    <AppUpdateProvider>
      <App />
    </AppUpdateProvider>
  </Provider>
);

Points clés

  • Les mises à jour ne fonctionnent que pour les bundles JS, sans plugins natifs.
  • Le bundle est archivé via npx @capgo/cli bundle zip — les autres méthodes sont incorrectes.
  • L'appel à notifyAppReady() est obligatoire dans les 10 premières secondes de lancement.
  • Comparaison de version : compare(currentVersion, newVersion, '<').
  • Capgo auto-hébergé — une alternative pour un contrôle total.

— Editorial Team

Advertisement 728x90

Lire ensuite