Skip to Content
DocumentationConcepts de base

Concepts de base

Cette section explique comment les éléments clés d’O3 s’articulent. À la fin, vous devriez comprendre comment O3 démarre et comment les modules sont chargés et configurés. Le schéma ci-dessous montre les principaux blocs et leurs liens.

Architecture d’O3

Notes sur le schéma (pour la clarté) : spa-assemble-config.json sert pendant l’assemblage d’une distribution à télécharger les packages de modules frontend et à produire les deux artefacts lus par l’app shell à l’exécution : importmap.json et routes.registry.json. Les modules ne se chargent pas directement depuis npm à l’exécution. Ils se chargent depuis les URLs de bundles dans la carte d’importation, ou depuis des URLs de serveur de dev local quand les overrides de carte d’importation et de routes sont actifs.

Les principaux éléments de l’architecture frontale d’O3 sont les suivants :

  • Le shell de l’application - la couche de base qui coordonne le démarrage et l’exécution.
  • Les modules frontaux - blocs UI composables.
  • La carte d’importation - un fichier JSON qui associe les noms de modules aux URLs de leurs bundles.
  • Le registre des routes - un fichier JSON qui indique au shell quelles pages, extensions, modales, workspaces et feature flags les modules fournissent.
  • Le core framework - bibliothèques et API partagées par les modules frontaux.

Où cela se trouve dans le code

Deux dépôts sont particulièrement utiles pour retrouver ces concepts dans le vrai code. Le monorepo openmrs-esm-core contient le runtime et l’outillage :

Le dépôt openmrs-distro-referenceapplication montre comment une vraie distribution utilise cet outillage. Son frontend/spa-assemble-config.json choisit les modules frontend et leurs versions, tandis que frontend/spa-build-config.json indique à l’app shell générée où trouver la carte d’importation et le registre des routes.

Shell de l’application

L’app shell est l’application hôte qui démarre O3 et coordonne le chargement et les services d’exécution. Introduit dans RFC-26 , il gère :

  • Démarrage : rend index.html, charge la carte d’importation et le registre des routes, puis connecte le chargement et le routage des modules.
  • Services d’exécution : définit points d’arrêt, abonnements (modales, toasts, notifications) et le mode hors ligne.
  • Couplage plateforme : initialise l’état global et met en place configuration et extensions.

Au démarrage, l’app shell n’exécute pas immédiatement tous les modules frontend. Il met en place les services UI de base, lit les balises <script type="systemjs-importmap"> et <script type="openmrs-routes"> dans index.html, enregistre les métadonnées déclarées dans le registre des routes, charge la configuration, puis démarre single-spa. Le code d’un module est récupéré plus tard, lorsqu’une route, une extension, une modale ou un workspace a réellement besoin d’une fonction de cycle de vie exportée par ce module.

Pour aller plus loin : Approfondir la coque d’application

Modules frontaux

Les modules frontaux sont les unités de fonctionnalité qui composent l’UI d’O3. Pensez à chaque module comme une mini‑application qui gère une partie de l’interface (par exemple, le dossier patient ou la navigation principale).

O3 traite ces modules comme des microfrontends (terme popularisé par single-spa ). L’app shell lit le registre des routes généré depuis les métadonnées de routes de chaque module sélectionné, enregistre les pages, extensions, modales, workspaces et feature flags déclarés, puis charge les fonctions de cycle de vie exportées par le module depuis la carte d’importation quand du code UI est nécessaire. Si un module exporte startupApp(), l’app shell l’appelle une fois avant de charger les fonctions de cycle de vie de ce module. Les modules exportent des fonctions de cycle de vie adaptées à single-spa, conformes à l’interface définie dans RFC-26 . Dans la plupart des distributions, la carte d’importation et le registre des routes sont générés pendant l’assemblage de la distribution à partir de spa-assemble-config.json et des métadonnées de routes des modules sélectionnés. Les extensions sont des blocs UI plug‑in que les modules définissent pour des emplacements nommés.

Notions essentielles (les fichiers que vous manipulerez le plus souvent) :

  • package.json - métadonnées, scripts et dépendances du module
  • src/index.ts - point d’entrée qui exporte fonctions de cycle de vie et code de démarrage
  • src/routes.json - métadonnées statiques pour l’app shell
  • src/config-schema.ts - où se trouvent les propriétés de configuration du module

Le code des modules frontaux est chargé à la demande par l’app shell lorsqu’il est nécessaire, ce qui améliore le temps de chargement initial.

Les modules frontaux peuvent vivre dans des dépôts autonomes ou dans des monorepos orientés domaine lorsque plusieurs modules partagent un même périmètre. Par exemple, les modules de gestion des patients (inscription, files d’attente, rendez-vous, gestion des lits, etc.) sont regroupés dans le monorepo openmrs-esm-patient-management.

Vous choisissez quels modules inclure dans une distribution en modifiant son fichier spa-assemble-config.json. Pour ajouter un module personnalisé, générez-le avec npm create @openmrs/o3-app@latest, publiez-le sur npm sous votre propre espace de noms, puis ajoutez une entrée pour ce module dans spa-assemble-config.json. Le dépôt template app  reste utile comme référence pour la structure de module générée.

Ensuite :

Carte d’importation

Une carte d’importation est une spécification du navigateur qui mappe des noms de modules vers leurs URLs de chargement. Introduite dans RFC-4 , elle indique au shell où récupérer chaque module. L’app shell précharge la carte au démarrage puis l’utilise pour résoudre et charger les bundles.

En pratique, les cartes d’importation sont générées et servies par la distribution (pas par l’app shell). Par exemple, la carte d’importation de l’application de référence de la communauté O3  est servie à /openmrs/spa/importmap.json, et la liste de modules et de versions qui la génère se trouve dans frontend/spa-assemble-config.json. La plupart des distributions suivent la même approche.

Pour voir la carte d’importation de votre distro dans le navigateur, naviguez vers /openmrs/spa/importmap.json (ou le chemin de base SPA de votre distro), où vous verrez un extrait simplifié comme:

{ "imports": { "@openmrs/esm-home-app": "./openmrs-esm-home-app-4.1.1-pre.211/openmrs-esm-home-app.js", "@openmrs/esm-login-app": "./openmrs-esm-login-app-4.3.2-pre.671/openmrs-esm-login-app.js", "@openmrs/esm-primary-navigation-app": "./openmrs-esm-primary-navigation-app-4.3.2-pre.671/openmrs-esm-primary-navigation-app.js", "@openmrs/esm-patient-chart-app": "./openmrs-esm-patient-chart-app-4.3.1-pre.1352/openmrs-esm-patient-chart-app.js" } }

Les clés de cet objet sont les noms des modules (identifiants uniques) et les valeurs sont des URLs de bundles. Ces URLs sont souvent des chemins relatifs dans les distributions assemblées, mais les overrides de développement local peuvent pointer vers des URLs absolues, par exemple un serveur de dev local. Le shell lit la carte d’importation à l’exécution lorsqu’il doit charger le code d’un module. Les modules frontend O3 actuels sont chargés comme des conteneurs Module Federation : l’app shell ajoute une balise script pour l’URL du bundle, puis appelle les méthodes init et get du conteneur pour charger les fonctions de cycle de vie exportées. Voir la page Approfondir la coque d’application pour les détails du chargement.

Pour aller plus loin : Chargement des modules

Registre des routes

Le registre des routes est un objet JSON qui associe les noms de modules aux métadonnées statiques provenant des fichiers routes.json de ces modules. L’app shell le lit au démarrage pour enregistrer :

  • Les pages et leurs routes
  • Les extensions et les slots auxquels elles s’attachent
  • Les modales, workspaces, groupes de workspaces et feature flags

Pendant l’assemblage d’une distribution, openmrs assemble extrait chaque module frontend sélectionné, lit son routes.json packagé, puis écrit le registre combiné dans routes.registry.json. En développement local, openmrs develop lit directement src/routes.json et sert un registre généré pour l’application en cours de développement.

C’est volontairement séparé de la carte d’importation. La carte d’importation répond à « où se trouve le bundle JavaScript de ce module ? » Le registre des routes répond à « quelles pages, extensions et autres points d’entrée UI ce module fournit-il ? » Un module a généralement besoin d’entrées aux deux endroits avant que son UI puisse s’afficher.

Comment O3 charge les modules (modèle mental rapide)

  1. L’app shell démarre et précharge la carte d’importation et le registre des routes.
  2. Il lit le registre des routes et enregistre les pages, extensions, modales, workspaces et feature flags déclarés.
  3. Quand une route, une extension, une modale ou un workspace a besoin de code, il résout l’URL du module dans la carte d’importation et charge ses fonctions de cycle de vie exportées.
  4. Le routeur monte les pages au fil de la navigation, et les slots d’extension montent les extensions lorsque leur UI hôte s’affiche.

Si vous devez changer…

  • Quels modules et versions sont inclus dans une distribution → modifiez spa-assemble-config.json.
  • Quelles pages ou extensions un module fournit → modifiez le fichier src/routes.json du module.
  • Comment les modules se chargent globalement → comportement de l’app shell et du chargement dynamique.
  • Ce que fait un module après son chargement → dépôt du module (UI, exports de cycle de vie, config et logique métier).

Cadre de base

Le framework O3 est la bibliothèque runtime partagée sur laquelle les modules frontend s’appuient. Il est publié sous @openmrs/esm-framework, mais dans le dépôt source il est composé de plusieurs packages ciblés sous packages/framework/*. Le package agrégé réexporte les API publiques de ces packages, ce qui permet aux modules d’importer le plus souvent depuis un seul endroit :

import { openmrsFetch, useConfig, ExtensionSlot, showToast } from "@openmrs/esm-framework";

Pensez au framework comme au contrat entre l’app shell et les modules frontend. L’app shell décide quels modules sont disponibles et quand leur code doit se charger. Le framework fournit les API que ces modules utilisent après leur chargement.

Les éléments les plus importants sont :

  • API backend et session : openmrsFetch, URLs de base REST, vérification des dépendances backend, helpers de session et d’utilisateur courant, utilitaires patient/visite et abonnements aux événements.
  • Systèmes de métadonnées runtime : schémas de configuration, enregistrement des extensions, slots d’extension, feature flags, stores globaux, contexte d’application et évaluation d’expressions.
  • Helpers de rendu et de cycle de vie : hooks React, composants Extension et ExtensionSlot, helpers de cycle de vie comme getSyncLifecycle et getAsyncLifecycle, et utilitaires qui adaptent les composants React aux cycles de vie single-spa.
  • Services UX partagés : composants du styleguide, navigation et fil d’Ariane, modales, workspaces, toasts, snackbars, notifications, traductions et prise en charge du mode hors ligne.

Pour les auteurs de modules, la règle pratique est d’utiliser le framework pour les comportements transversaux d’O3 au lieu d’inventer localement des wrappers de fetch, de l’état global, du câblage d’extensions, du chargement de configuration ou une UI de notification. Si vous devez modifier le comportement global de ces systèmes partagés, ce changement appartient généralement à openmrs-esm-core, pas à un module frontend individuel.

Pour aller plus loin : Référence de l’API du framework

Prochaines étapes

Prêt à construire ? Continuez avec Modules frontend pour voir comment les modules sont structurés et chargés.

Dernière mise à jour le