Créer des configurations d’environnement

UNE ASSISTANCE TECHNIQUE ? NOUS SOMMES DISPONIBLES UNE ASSISTANCE TECHNIQUE ? NOUS SOMMES DISPONIBLES

Accéder au sommaire de “Guide pratique du développeur React Native”

Ce chantier fait également partie des aspects qu’il est primordial de mettre en place dès le début d’un projet. D’autant plus que React Native, contrairement à React JS, s’appuie sur des environnements natifs externes que sont iOS, Android (et bientôt Windows). Lorsque vous définissez des variables d’environnement, ces variables sont utilisées dans le code JavaScript mais aussi et surtout dans les environnements cibles natifs. A titre d’exemple, Android s’appuie sur l’outil Gradle pour la construction des projets, il faut donc trouver un outil capable de modifier des fichiers de propriété gradle ou un fichier AndroidManifest.xml.

Avant de prendre connaissance de cet article, je vous invite à lire la méthodologie 12 Facteurs, indispensable pour comprendre le principe de configuration d’environnement, notamment la partie 3 (très courte).

Globalement il existe 2 façons de gérer les configurations :

  • En utilisant un outil spécialisé
  • Manuellement en s’appuyant directement sur les variables d’environnement ou un fichier JSON (voir pointeurs)

Nous nous focalisons ici sur la première solution. La seconde est plus simple mais moins adaptée aux environnements complexes.

Mode de fonctionnement

L’idée sous-jacente consiste à partir du principe que les variables liées à la configuration d’un environnement (DEV, TEST, PROD, …) doivent être stockées de manière sécurisée sans nécessiter de changement de code source en cas de changement de cible. Le code source doit être stable et ne pas être impacté par un changement lié à une valeur de configuration. Ce n’est pas toujours possible car il est nécessaire parfois de bouchonner des composants en développement pour des raisons de performances et d’efficacité. Mais il faut essayer d’être le plus indépendant possible.

La plupart des outils de gestion de configuration opèrent de la même manière. Vous définissez un fichier contenant des propriétés : dev.env, prod.env. test.env, situés à la racine du projet, suffisamment visibles. Ces fichiers ne sont jamais commités dans le gestionnaire de code source avec leurs vraies valeurs.

Fichier env.dev
API_URL=https://monserveur/api
POSTGRES_HOST=dossarddb
POSTGRES_PORT=5432
POSTGRES_DB=dossarddb
POSTGRES_USER=dossarduser
POSTGRES_PASSWORD=dossardpwd
MONITORING_PASSWORD=admin
MONITORING_USER=admin
JWT_SECRET=JWT_SECRET
JWT_EXPIRE_SECONDS=360000
ENV=DEV

Ce fichier est ensuite référencé directement dans le code sur le principe suivant :

Fichier main.tsx
import Config from "react-native-config";

Config.API_URL; // 'https://monserveur/api'
Config.POSTGRES_HOST; // 'dossarddb'
Config.POSTGRES_USER; // 'dossarduser'
...

Lors de la phase de compilation du projet, ces outils fusionnent les valeurs des propriétés avec le code compilé. Ces mêmes variables peuvent être utilisées directement à partir des environnements natifs via des outils tels que Gradle ou XCode.

Voici plusieurs exemples d’utilisation des variables API_URL, APP_ID, API_KEY dans un fichier Java Android, un fichier de configuration Gradle et un fichier manifest.

Fichier Main.java
public HttpURLConnection getApiClient() {
    URL url = new URL(BuildConfig.API_URL);
    // ...
}
Fichier build.gradle
defaultConfig {
    applicationId project.env.get("APP_ID")
}
// Un exemple utilisant la version courante 
versionCode project.env.get("VERSION_CODE").toInteger()
Fichier manifest.xml (Android)
<meta-data
  android:name="com.google.android.geo.API_KEY"
  android:value="@string/GOOGLE_MAPS_API_KEY" />

Le même principe existe pour iOS, voici un fichier Objective C référençant la variable API_URL.

Fichier AppDelegate.m (iOS)
// import header #import "ReactNativeConfig.h" 
// then read individual keys like : 
NSString *apiUrl = [ReactNativeConfig envFor:@"API_URL"]; 
// or just fetch the whole config 
NSDictionary *config = [ReactNativeConfig env];

Définir l’environnement cible

Le lancement de l’application avec l’environnement cible s’effectue de la manière suivante :

$ ENVFILE=dev.env react-native run-ios           # bash
$ SET ENVFILE=dev.env && react-native run-ios    # windows

Dans le cas de l’outil react-native-config, la variable ENVFILE définit le fichier cible. D’autres outils s’appuient directement sur les variables d’environnement.

Il suffit de lancer la commande suivante pour générer une version DEV de l’application mobile sous Android :

$ cd android && ENVFILE=dev.env ./gradlew assembleRelease

Avec ce mode de fonctionnement, il est relativement aisé d’ajouter de nouveaux environnements de configuration (préprod2, demo, etc …). Ce sont de nouveaux fichiers contenant de nouvelles valeurs.

A noter que des outils tels que react-native-config ne sont pas obligatoires, certains projets préfèrent s’appuyer directement sur un fichier JSON mais avec l’inconvénient de devoir réaliser le parsing manuellement. Typiquement le fichier Objective C précédent aurait nécessité un travail plus approfondi pour extraire la variable du bon fichier JSON.

Bibliographie

Managing Configuration in React Native (Approche react-native-config)

Custom React Native Configuration – A simple solution (Approche manuelle)

UNE ASSISTANCE TECHNIQUE ? NOUS SOMMES DISPONIBLES UNE ASSISTANCE TECHNIQUE ? NOUS SOMMES DISPONIBLES