Fermer

novembre 3, 2021

Une plongée profonde dans l'interface utilisateur sans serveur avec TypeScript


Résumé rapide ↬

L'interface utilisateur sans serveur est simplement un utilitaire de ligne de commande gratuit et open source permettant de créer et de déployer rapidement des applications sans serveur sur la plate-forme AWS. Dans cet article, nous allons apprendre et couvrir tout ce dont vous avez besoin pour utiliser l'interface utilisateur sans serveur pour déployer nos projets ou applications sans serveur vers des fournisseurs de services cloud.

Si vous cherchez une explication claire sur la façon dont les applications peuvent être développées et déployées sur AWS avec le moins de configuration possible, alors j'ai préparé l'article pour vous. Nous allons tout diviser en deux parties : déployer une application Web statique (dans ce cas, une application Notes), puis une application Web sans serveur sur CloudFront à l'aide de la bibliothèque d'interface utilisateur sans serveur.

Note : Pour suivre, vous aurez besoin d'une compréhension de base d'AWS et du développement Web afin de comprendre comment le projet TypeScript est construit et utilisé pour être déployé sur AWS.

Exigences

Avant de commencer à construire notre projet, les éléments suivants les exigences doivent être remplies :

  • Connaissance de base de React, React Hooks et Material UI ;
  • Bonne connaissance de TypeScript ;
  • Node.js version >= 12.xx installé sur votre machine locale ;
  • Avoir un compte AWS vérifié ;
  • Configuré votre AWS CLI avec des informations d'identification locales ;
  • Assurez-vous que npm ou yarn est également installé en tant que gestionnaire de packages .

Introduction

Nous commencerons par quelques introductions sur l'interface utilisateur sans serveur , mais à la fin de ce didacticiel, vous devriez être en mesure d'utiliser confortablement l'interface utilisateur sans serveur dans vos applications, de l'installation à la compréhension des concepts et à sa mise en œuvre dans vos propres projets. Selon les docs sur GitHub :

« L'interface utilisateur sans serveur est simplement un utilitaire de ligne de commande gratuit et open source permettant de créer et de déployer rapidement des applications sans serveur sur la plate-forme AWS. »

Comme indiqué, il s'agit d'une bibliothèque légère qui s'installe rapidement sur le terminal et peut être utilisée pour configurer un domaine, déployer des sites Web statiques ou sans serveur, le tout sur le terminal. Cela vous permet de coupler facilement n'importe quel choix de cadre frontal avec l'interface utilisateur sans serveur pour déployer des applications existantes et nouvelles sur AWS sans stress.

L'interface utilisateur sans serveur fonctionne également très bien avec n'importe quel site Web statique et les sites Web qui utilisent des fonctions sans serveur pour gérer les demandes à une sorte d'API. Cela le rend idéal pour créer des applications back-end sans serveur. Le processus de déploiement via l'interface utilisateur sans serveur vous donne le contrôle pour déployer automatiquement chaque partie ou, en d'autres termes, l'itération de votre application avec une URL différente et distincte. Cependant, cela signifie que vous pouvez surveiller l'intégration et les tests continus de votre application en toute confiance et en temps réel.

En utilisant l'interface utilisateur sans serveur en production, vous pouvez choisir d'écrire votre projet ou vos fonctions sans serveur en JavaScript ou TypeScript natif. Dans tous les cas, ils seront regroupés très rapidement et vos fonctions déployées en tant que fonctions Lambda Node.js 14. Vos fonctions dans le dossier ./functions sont déployées automatiquement en tant que fonctions sans serveur sur AWS. Cette approche signifie que nous écrirons notre code sous la forme de fonctions qui géreront différentes tâches ou demandes au sein de l'application. Ainsi, lorsque nous déployons nos fonctions, nous les invoquerons sous la forme d'un événement.

Ensuite, le besoin d'un fichier d'application rapide et très petit fait que l'interface utilisateur sans serveur est essentielle au sein de notre application. Étant un outil de ligne de commande, il n'a pas besoin d'être intégré à l'application — il peut être installé globalement, npm install -g @serverlessui/cli ou en tant que devDependency dans notre candidature. Cela signifie qu'aucune taille de fichier n'a été ajoutée à notre application, ce qui nous donne l'avantage de n'avoir que le code nécessaire au fonctionnement de notre application. Aucune taille de paquet supplémentaire supplémentaire à notre application. Comme pour toute migration, nous, les développeurs, savons que la migration d'applications existantes peut être difficile et troublante sans temps d'arrêt pour nos utilisateurs, mais cela est faisable en fonction du cas d'utilisation.

Plus après le saut ! Continuez à lire ci-dessous ↓

Avantages et inconvénients de l'utilisation de l'interface utilisateur sans serveur

L'utilisation de l'interface utilisateur sans serveur dans nos projets, qu'ils soient existants ou nouveaux, présente certains avantages qu'elle nous apporte :[19659006]Il n'y a pas de services intermédiaires contrairement aux autres ; L'interface utilisateur sans serveur vous offre les avantages prêts à l'emploi d'une infrastructure préconfigurée sans avoir à passer par un intermédiaire.

  • Elle prend en charge et fonctionne dans presque tous les environnements CI (Intégration continue) grâce à cela c'est un outil en ligne de commande facilement disponible via npm. C'est un plus pour la configuration du backend et de l'infrastructure. L'interface utilisateur sans serveur offre presque toutes les options lors du déploiement de votre application : déployez votre site Web statique, les fonctions Lambda ou le code de production.
  • Presque toutes les configurations (telles que configure-domain et le déploiement d'applications) sont toutes effectuées sur la commande line.
  • Les frameworks frontaux tels que React, Svelte, Vue ou JQuery sont tous pris en charge, tant qu'ils se compilent en code statique.
  • Donne aux applications sans serveur la possibilité de s'adapter dynamiquement par requête, et ne le fera pas nécessitent une planification ou un approvisionnement de capacité pour l'application.
  • Ce sont quelques inconvénients de l'interface utilisateur sans serveur que nous devrions considérer avant de décider de l'utiliser dans nos projets :

    • Il ne prend en charge que les projets construits à l'aide de TypeScript ou JavaScript dans le projet. AWS.

    Lecture recommandée : Test local d'une API sans serveur (API Gateway et Lambda)

    Configuration de l'application Notes

    Aujourd'hui, plusieurs outils sont disponibles pour permettre aux développeurs de gérer efficacement infrastructures, par exemple, l'Serverless UIla console ou l'un des frameworks disponibles en ligne. Comme expliqué ci-dessus, notre objectif est de mettre en place une simple démonstration d'une application Notes en TypeScript, ce qui nous aidera rapidement à démontrer comment l'interface utilisateur sans serveur peut être utilisée pour l'héberger, afin que vous puissiez rapidement la comprendre et l'implémenter dans vos propres projets.

    Pour ce didacticiel, nous allons rapidement explorer et expliquer les différentes parties d'une application Notes, puis installer la bibliothèque Serverless UI pour héberger l'application sur AWS.

    Nous procédons au clonage du référentiel distant. sur notre machine locale et exécutez la commande qui installera toutes les dépendances.

    git clone https://github.com/smashingmagazine/serverless-UI-typescript.git
    
    wire install

    La commande ci-dessus clone une application Note dont les composants fonctionnels sont déjà construits, puis procède à l'installation des dépendances nécessaires au fonctionnement des composants. Voici la liste des dépendances requises pour que cette application Notes fonctionne :

    {
      ...
      "dépendances": {
        "@testing-library/jest-dom": "^5.11.4",
        "@testing-library/react": "^11.1.0",
        "@testing-library/user-event": "^12.1.10",
        "@types/jest": "^26.0.15",
        "@types/node": "^12.0.0",
        "@types/react": "^17.0.0",
        "@types/react-dom": "^17.0.0",
        "react": "^17.0.1",
        "react-dom": "^17.0.1",
        "react-scripts": "4.0.3",
        "typescript": "^4.1.2",
        "web-vitals": "^1.0.1"
      },
      ...
    }
    

    La liste ci-dessus contient des dépendances et leurs définitions de type pour fonctionner de manière optimale avec TypeScript. Nous procédons à l'explication des parties de travail de l'application. Mais définissons d'abord les interfaces pour les données Note et l'argument Props qui seront transmis à nos fonctions. Créez un fichier /src/interfaces.ts et incluez les éléments suivants :

    export interface INote {
      note : chaîne ;
    }
    Exporter les accessoires d'interface {
      contenu : INote ;
      delContent(noteToDelete: string): void;
    }

    Ici, nous définissons la structure de type qui agit comme un contrat de syntaxe entre nos composants et les accessoires qui y sont passés. Définit également les données unitaires de l'état de notre application, INote.

    Pour cette application, nous nous concentrerons principalement sur le dossier /src/components et le /src Fichier /App.tsx. Nous commencerons par le dossier components puis expliquerons progressivement le reste de l'application.

    Remarque : Les styles définis et utilisés dans cette application Notes se trouvent dans /src Fichier /App.css.

    Le dossier components contient un fichier, le fichier Note.tsx ; qui définira la structure de l'interface utilisateur de chaque donnée de note que nous créons.

    import { INote } à partir de "../Interfaces" ;
    
    accessoires d'interface {
      contenu : INote ;
      delContent(noteToDelete: number): void;
    }
    
    const Remarque = ({ contenu, delContent } : accessoires) => {
      revenir (
        
    {content.note}
    ); } ; exportation par défaut Remarque ;

    Dans la fonction Notenous déstructurons un paramètre props qui a la définition de type de données de Propset contient le content et champs delContent. Le champ content contient en outre le champ note dont la valeur sera la valeur d'entrée de nos utilisateurs. Alors que le champ delContent est une fonction pour supprimer content de l'application.

    Nous allons procéder à la construction de l'interface utilisateur générale de l'application, en définissant ses deux sections ; une pour créer les notes et l'autre pour contenir la liste des notes déjà créées :

    const App : FC = () => {
      revenir (
        
    ); } ; export default App;

    La balise div avec la classe header contient les éléments input et button pour créer et ajouter des notes à l'application :

    const App : FC = () => {
      revenir (
        
    ...
    ); } ; export default App;

    Dans le code ci-dessus, nous avons enregistré un nouvel état, noteContentpour la valeur de l'élément input. Également un événement onChange pour mettre à jour la valeur input. L'élément button a l'événement onClick qui gérera la génération de nouveau contenu à partir de la valeur de l'entrée et son ajout à l'application. Le balisage de l'interface utilisateur ci-dessus, associé aux styles déjà définis, ressemblera à :

    Le composant d'en-tête

    Le composant d'en-tête. ( Grand aperçu)

    Définissons maintenant les nouveaux états, noteContent et noteListpuis les deux événements, handleChange et addNote fonctions pour mettre à jour nos fonctionnalités de l'application :

    import { FC, ChangeEvent, useState } à partir de "react" ;
    importer "./App.css" ;
    importer { INote } de "./Interfaces" ;
    
    Const App : FC = () => {
      const [noteContent, setNoteContent] = useState("");
      const [noteList, setNoteList] = useState([]);
    
      const handleChange = (événement : ChangeEvent) => {
          setNoteContent(event.target.value.trim());
      } ;
    
      const addNote = (): void => {
        const newContent = { Date.now(), note : noteContent } ;
        setNoteList([...noteList, newContent]);
        setNoteContent("");
      } ;
      
      revenir (
        
    ...
    ); } ; exporter l'application par défaut ;

    L'état noteList contient toutes les notes créées dans l'application. Nous en ajoutons et en supprimons pour mettre à jour l'interface utilisateur avec plus de notes créées. Dans la fonction handleChangenous mettons régulièrement à jour noteContent avec les modifications apportées au champ de saisie à l'aide de la fonction setNoteContent. La fonction addNote crée un objet newContent avec un champ note dont la valeur est obtenue à partir de noteContent. Il appelle ensuite les fonctions setNoteList et crée un nouveau tableau noteList à partir de son état précédent et newContent.

    La prochaine étape consiste à mettre à jour la deuxième section du L'application fonctionne avec le code JSX pour contenir la liste des notes créées :

    ...
    
    importer la note de "./Components/Note" ;
    
    Const App : FC = () => {
      ...
    
      revenir (
        
    ...
    {noteList.map((contenu : INote) => { retour ; })}
    ); } ; exporter l'application par défaut ;

    Nous parcourons la noteList en utilisant la méthode Array.prototype.map pour créer le dump de notes dans notre application. Ensuite, nous avons importé le composant Note qui définit l'interface utilisateur de notre note, en lui passant les accessoires keycontent et delContent. La fonction delContent comme indiqué précédemment supprime content de l'application :

    ...
    importer la note de "./Components/Note" ;
    
    Const App : FC = () => {
      ...
      const [noteList, setNoteList] = useState([]);
    
      ...
    
      const delContent = (noteID : nombre) => {
        setNoteListe(
          noteList.filter((contenu) => {
            return content.id !== noteID;
          })
        );
      } ;
      revenir (
        
    ...
    {noteList.map((contenu : INote) => { retour ; })}
    ); } ; exporter l'application par défaut ;

    La fonction delContent filtre de noteList les contenu qui ne sont en aucun cas équivalents aux noteToDelete argument. noteToDelete est équivalent à content.note mais est transmis à delContent chaque fois qu'une note est créée en appelant le composant Note.[19659016]En couplant les deux sections du composant Appvotre code devrait ressembler à ce qui suit :

    import { FC, ChangeEvent, useState } from "react" ;
    importer "./App.css" ;
    importer la note de "./Components/Note" ;
    importer { INote } de "./Interfaces" ;
    
    Const App : FC = () => {
      const [noteContent, setNoteContent] = useState("");
      const [noteList, setNoteList] = useState([]);
    
      const handleChange = (événement : ChangeEvent) => {
          setNoteContent(event.target.value.trim());
      } ;
    
      const addNote = (): void => {
        const newContent = { id : Date.now(), note : noteContent } ;
        setNoteList([...noteList, newContent]);
        setNoteContent("");
      } ;
    
      const delContent = (noteID: nombre): void => {
        setNoteListe(
          noteList.filter((contenu) => {
            return content.id !== noteID;
          })
        );
      } ;
    
      revenir (
        
    {noteList.map((contenu : INote) => { retour ; })}
    ); } ; exporter l'application par défaut ;

    Et si nous ajoutons quelques notes à notre application, notre interface utilisateur finale ressemblera à ceci :

    L'application Notes

    Application Notes. ( Grand aperçu)

    Maintenant que nous avons créé une application Notes simple que nous pouvons ajouter et supprimer des notes, passons à l'utilisation de l'interface utilisateur sans serveur pour déployer cette application sur AWS et déployez également une application principale sans serveur (fonctions sans serveur).

    Déploiement de l'application Notes avec l'interface utilisateur sans serveur

    Maintenant que nous avons terminé d'expliquer les composants qui composent notre application Notes, il est temps de déployer notre application à l'aide de l'interface utilisateur sans serveur sur le terminal. La première étape du déploiement de notre application sur AWS consiste à configurer l'AWS CLI sur notre machine. Vérifiez ici pour connaître les étapes complètes à suivre.

    La prochaine étape consiste à installer la bibliothèque d'interface utilisateur sans serveur globalement sur notre machine locale :

    npm install -g @serverlessui/cli[19659040]Cela installe le package globalement, ce qui signifie qu'aucune taille de fichier supplémentaire n'a été ajoutée dans le code de construction. :
    
    
    sui deploy --dir="build"
    ...
    ❯ URL du site Web : https://xxxxx.cloudfront.net

    Mais pour notre projet, nous exécuterons la commande yarn qui construit notre application dans un site Web statique dans le buildaprès quoi nous exécutons la commande Serverless UI pour déployer l'application :

    yarn build
    ...
    Fait en 80.63s.
    
    sui deploy --dir="build"
    ...
    
    ✅ ServerlessUIAppPreview1c9ec9f1
    
    Les sorties:
    ServerlessUIAppPreview1c9ec9f1.ServerlessUIBaseUrlCA2DC891 = https://dal254gl37fow.cloudfront.net
    
    ARN de pile :
    arn:aws:cloudformation:us-west-2:261955174750:stack/ServerlessUIAppPreview1c9ec9f1/e4dc82e0-fe44-11eb-b959-064619847e85
    

    Notre application a été déployée avec succès et le temps total de déploiement a été inférieur à cinq minutes. L'application a été déployée sur Cloudfront ici. Plateforme Web AWS. Avec l'interface utilisateur sans serveur, nous supprimerons les tracas liés à la configuration et à la configuration avant de la déployer sur AWS.

    Vous voudrez également vous assurer que votre environnement local est aussi proche que possible de l'environnement de production. Cela inclut le runtime, la version Node.js. Pour rappel, vous devez installer une version de Node.js prise en charge par AWS Lambda.

    Le code ou le dossier /serverless utilisé dans cette partie de l'article se trouve ici. Ce dossier contient le fichier source, qui fait une requête à une API pour obtenir une note aléatoire ; une blague.

    const nodefetch = require("node-fetch");
    
    exports.handler = async (événement, contexte) => {
      const url = "https://icanhazdadjoke.com/" ;
      essayer {
        const jokeStream = wait nodefetch(url, {
          en-têtes : {
            Accepter : "application/json"
          }
        });
        const jsonJoke = wait jokeStream.json();
        revenir {
          code d'état : 200,
          corps : JSON.stringify(jsonJoke)
        } ;
      } attraper (err) {
        return { statusCode : 422, corps : err.stack } ;
      }
    };

    Avant de déployer le dossier serverlessnous devons installer la bibliothèque esbuild. Cela contribuera à rendre le regroupement des fichiers d'application plus rapide et accessible.

    npm install esbuild --save-dev

    La prochaine étape pour déployer la fonction sans serveur sur AWS consiste à spécifier l'emplacement du dossier avec - -functions comme nous l'avons fait précédemment avec le drapeau --dist lors du déploiement de notre site Web statique.

    sui deploy --functions="serverless"

    Alors que la commande ci-dessus nous aide à construire notre application, la fonction sans serveur la déploie avec succès :

    ...
     
    ✅ ServerlessUIAppPreview560dbd41
    
    Les sorties:
    ServerlessUIAppPreview560dbd41.ServerlessUIFunctionPathjokesD9F032B9 = https://dwh6k64yrlqcn.cloudfront.net/api/jokes
    
    ARN de pile :
    arn:aws:cloudformation:us-west-2:261955174750:stack/ServerlessUIAppPreview560dbd41/21de6780-fb93-11eb-a0fb-061a2a83f0b9
    • La fonction sans serveur est maintenant déployée sur Cloudfront ici.[19659030]En remarque, nous devrions pouvoir référencer notre URL API par chemin relatif dans notre code d'interface utilisateur comme /api/jokes au lieu de l'URL complète si elle est déployée en même temps avec /dist ou /build dossier. Cela devrait toujours fonctionner, même avec CORS, car l'interface utilisateur et l'API se trouvent sur le même domaine.

      Mais par défaut, Serverless Ui créera une nouvelle pile pour chaque aperçu déployé, ce qui signifie que chaque URL sera différente et unique. Afin de déployer plusieurs fois sur la même URL, l'indicateur --prod doit être transmis.

      sui deploy --prod --dir="dist" --functions="serverless"[19659040]Créons un dossier /src/components/Quote et à l'intérieur créons un fichier index.tsx. Il contient le code JSX pour héberger les guillemets.
      
      
      import { useState } de "react" ;
      
      Citation const = () => {
        const [joke, setJoke] = useState();
        revenir (
          

      {blague}

      ); } ; export default Quote;

      Ensuite, nous allons demander aux fonctions sans serveur déployées d'en récupérer une blague dans un intervalle de temps défini. De cette façon, la note, c'est-à-dire la blague, dans le balisage

      {joke}

      JSX est mise à jour toutes les 2000 millisecondes.
      import { useEffect, useState } à partir de "react" ;
      
      Citation const = () => {
        const [joke, setJoke] = useState();
      
        useEffect(() => {
          const getRandomJokeEveryTwoSeconds = setInterval(async () => {
            const url = process.env.API_LINK || "https://dwh6k64yrlqcn.cloudfront.net/api/jokes" ;
            const jokeStream = wait fetch(url);
            const res = wait jokeStream.json();
            const blague = res.blague;
            setJoke(blague);
          }, 2000);
          retour () => {
            clearInterval(getRandomJokeEveryTwoSeconds);
          } ;
        }, []);
      
        revenir (
          

      {blague}

      ); } ; export default Quote;

      L'extrait de code ajouté au code source ci-dessus utilisera le hook useEffect pour effectuer des appels d'API vers les fonctions sans serveur, mettant à jour l'interface utilisateur avec les blagues renvoyées par la requête en utilisant le setJoke fonction fournie par le hook useState.

      Redémarrons notre serveur de développement local pour voir les nouvelles modifications ajoutées à notre interface utilisateur :

      Incorporé une fonction sans serveur qui s'exécute toutes les deux secondes dans l'application Notes

      Application Notes avec une fonction sans serveur exécutée dessus. ( Grand aperçu)

      Avant de déployer les mises à jour sur votre application existante, vous pouvez configurer un domaine personnalisé et, à l'aide de l'interface utilisateur sans serveur, déployer et envoyer les mises à jour de code suivantes sur ce domaine personnalisé.

      Configurer le domaine avec l'interface utilisateur sans serveur

      Nous pouvons déployer notre application sans serveur à notre domaine personnalisé plutôt que celui par défaut fourni par CloudFront. La configuration et le déploiement sur notre domaine personnalisé peuvent prendre 20 à 48 heures pour se propager complètement, mais ne doivent être terminés qu'une seule fois. Accédez au répertoire de votre projet et exécutez la commande :

      sui configure-domain --domain=""

      Remplacez la valeur ci-dessus du drapeau --domain par votre propre URL personnalisée . Ensuite, vous pouvez continuellement mettre à jour le projet déjà déployé en ajoutant l'indicateur --prod lorsque vous utilisez à nouveau la commande sui deploy.

      Lecture recommandée : Building A Formulaire de contact sans serveur pour votre site statique. De plus, nous avons créé une démo d'une application Notes simple et l'avons déployée avec la bibliothèque. Vous pouvez également créer des fonctions back-end sans serveur déclenchées par des événements se produisant avec l'application et les déployer sur votre AWS lambda.

      Pour le cas d'utilisation avancé de l'interface utilisateur sans serveur, nous avons configuré le domaine par défaut fourni par CloudFront avec le nôtre. nom de domaine personnalisé à l'aide de Interface utilisateur sans serveur. Et pour les projets sans serveur existants ou ceux qui peuvent avoir une infrastructure CloudFormation et/ou CDK supplémentaire, l'interface utilisateur sans serveur fournit des constructions CDK pour chacune des actions CLI. Et avec l'interface utilisateur sans serveur, nous pouvons facilement configurer un compartiment S3 privé - une fonctionnalité supplémentaire souhaitée pour une sécurité renforcée sur nos applications sans serveur. Cliquez ici pour en savoir plus à ce sujet.

      • Le code utilisé dans cet article se trouve sur Github.

      Ressources

      Smashing Editorial" width ="35" height="46" loading="lazy" decoding="async(ks, vf, yk, il)




    Source link