AccueilClients

Applications et sites

  • Application métiersIntranet, back-office...
  • Applications mobilesAndroid & iOS
  • Sites InternetSites marketings et vitrines
  • Expertises techniques

  • React
  • Expo / React Native
  • Next.js
  • Node.js
  • Directus
  • TypeScript
  • Open SourceBlogContactEstimer

    29 janvier 2025

    App universelle avec Expo

    5 minutes de lecture

    App universelle avec Expo
    🇺🇸 This post is also available in english

    App universelle avec Expo

    Au fil des années, Expo a considérablement amélioré sa plage de fonctionnalités, devenant une solution viable pour développer des applications multi-plateformes. Dans cet article, nous allons explorer la création d'une application universelle.

    Qu'est-ce qu'une application universelle ?

    On parle d'application universelle lorsqu'une seule base de code est utilisée pour créer une application qui peut être exécutée sur plusieurs plateformes, en général web, iOS et Android, mais cela peut aussi concerner d'autres plateformes comme Windows, macOS, etc. L'intérêt principal de cette solution est de réduire le temps de développement et de maintenance, car il n'est pas nécessaire de maintenir plusieurs bases de code.

    Pourquoi une application universelle ?

    En général, la mise en place d'un export Web survient pour des applications développées en priorité pour les plateformes mobiles. L'idée étant d'offrir une expérience similaire sur un navigateur web, sans avoir à développer une application web à part entière. C'est par exemple le cas de BlueSky À noter qu'il est possible d'adapter des composants pour une utilisation spécifique au Web grâce aux extensions de fichiers par plateforme.

    Pourquoi utiliser Expo ?

    Au-delà d'être un SDK pour application mobile, Expo fournit tout l'outillage nécessaire pour démarrer très rapidement une application universelle, de par son intégration de React Native Web. Accompagné de EAS, le déploiement d'une application Expo sur toutes les plateformes devient un jeu d'enfant, notamment depuis la sortie en preview publique de EAS Hosting.

    Quelle stack technique ?

    Pour cet exemple, nous utiliserons la stack technique suivante :

    Le choix de Tamagui est motivé par sa simplicité d'utilisation, sa bibliothèque de composants bien fournie et surtout une compatibilité Web avec notamment la compilation au build time d'une feuille de style CSS.

    Création et configuration du projet

    Pour commencer, créons un nouveau projet Expo :

    bunx create-expo-app my-universal-app
    cd my-universal-app
    

    Ajoutons ensuite les dépendances externes qui ne sont pas installées par défaut :

    bun add tamagui @tamagui/config @tamagui/babel-plugin
    

    Créons ensuite un fichier de configuration pour Tamagui à la racine :

    tamagui.config.ts
    import { defaultConfig } from "@tamagui/config/v4";
    import { createTamagui } from "tamagui";
    
    export const config = createTamagui(defaultConfig);
    
    type CustomConfig = typeof config;
    
    declare module "tamagui" {
      interface TamaguiCustomConfig extends CustomConfig {}
    }
    

    Puis ajoutons le plugin Babel de Tamagui à notre fichier babel.config.js :

    babel.config.js
    module.exports = {
      presets: ["babel-preset-expo"],
      plugins: ["@tamagui/babel-plugin"],
    };
    

    Création de la première page

    Supprimons les fichiers créés par défaut dans le dossier app. Pour le fichier +not-found.tsx, nous allons juste retourner null. Modifions notre _layout.tsx :

    _layout.tsx
    import { useColorScheme } from "@/hooks/useColorScheme";
    import { config } from "@/tamagui.config";
    import {
      DarkTheme,
      DefaultTheme,
      ThemeProvider,
    } from "@react-navigation/native";
    import { Stack } from "expo-router";
    import { StatusBar } from "expo-status-bar";
    import "react-native-reanimated";
    import { TamaguiProvider } from "tamagui";
    
    export default function RootLayout() {
      const colorScheme = useColorScheme();
    
      return (
        <TamaguiProvider
          config={config}
          defaultTheme={colorScheme === "dark" ? "dark" : "light"}
        >
          <ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
            <Stack>
              <Stack.Screen name="index" options={{ headerShown: false }} />
              <Stack.Screen name="+not-found" />
            </Stack>
            <StatusBar style="auto" />
          </ThemeProvider>
        </TamaguiProvider>
      );
    }
    

    Puis créons un fichier index.tsx :

    index.tsx
    import { H1, Stack } from "tamagui";
    
    const HomePage = () => {
      return (
        <Stack justify="center" items="center" flex={1}>
          <H1>Universal app example</H1>
        </Stack>
      );
    };
    
    export default HomePage;
    

    Lancement de l'application

    Pour lancer l'application, exécutons la commande suivante :

    bun start
    

    Le bundler Metro utilisé par Expo sera lancé. Il suffit ensuite d'appuyer soit sur w pour lancer l'application web, soit sur i pour lancer l'application iOS, soit sur a pour lancer l'application Android.

    Ajout d'une route API

    Depuis la version 3 d'Expo Router, il est possible d'exposer des routes API, de la même manière que le fait Next.js. Nous allons créer une route api /hello, qui renverra un simple message dans un JSON :

    app/hello+api.ts
    export const GET = () => {
      return Response.json({ message: "Hello from API" });
    };
    

    Modifions notre fichier index.tsx pour ajouter un bouton qui appellera notre route API :

    index.tsx
    import { Button, H1, Stack } from "tamagui";
    
    const HomePage = () => {
      const onSayHello = async () => {
        const response = await fetch("/hello");
    
        if (response.ok) {
          const json = await response.json();
          alert(json.message);
        } else {
          alert("Error");
        }
      };
    
      return (
        <Stack justify="center" items="center" flex={1} gap="$4">
          <H1>Universal app example</H1>
          <Button theme="blue" size="$5" onPress={onSayHello}>
            Say hello to API
          </Button>
        </Stack>
      );
    };
    
    export default HomePage;
    
    Il faut modifier la propriété expo.web.output avec la valeur server dans le fichier app.json afin d'utiliser les routes API.

    Et voilà, en l'espace de quelques minutes, nous avons configuré une application universelle avec Expo, exposant en plus de cela une route API.

    App universelle sur 3 iOS, Android et Web

    Déploiement

    Avant de déployer sur un serveur distant, il est possible de tester l'application web en local en exécutant la commande suivante :

    npx expo export -p web
    npx expo serve
    

    Pour déployer l'application sur un serveur distant, nous utiliserons EAS Hosting :

    npx expo export -p web
    eas deploy
    

    Et voilà, l'application est maintenant accessible sur le web. Un dashboard est disponible sur EAS afin de visualiser les différentes requêtes entrantes, de la même manière que le fait Vercel.

    Dashboard EAS

    Conclusion

    Expo est une solution de plus en plus mature pour le développement d'applications universelles. Grâce à EAS, le déploiement d'une application Expo sur toutes les plateformes devient un jeu d'enfant. Tamagui permet de créer rapidement une interface compatible sur toutes les plateformes, le tout optimisé pour les performances.

    Il faut cependant prendre en compte qu'actuellement, l'export web est une SPA, il n'y a donc aucun rendu serveur comme on pourrait avoir sur Next.js. À ce jour, cette fonctionnalité est au stade d'expérimentation et pourrait voir le jour dans une future version. En attendant, si vous souhaitez utiliser Next.js, l'utilisation d'un monorepo est à privilégier. C'est notamment ce qui est utilisé dans le template de base de Tamagui.

    À découvrir également

    Premier Octet vous accompagne dans le développement de vos projets avec react-native

    Discuter de votre projet react-native