Fermer

octobre 26, 2021

Optimiser les applications Next.js avec Nx —


Résumé rapide ↬

Nx est un cadre de construction qui facilite l'optimisation, la mise à l'échelle efficace des applications et d'autres fonctionnalités telles que les bibliothèques et les composants partagés. Dans cet article, nous verrons comment mettre à l'échelle efficacement les applications Next.js en utilisant Nx.

Dans cet article, nous verrons comment optimiser et créer une application Next.js hautes performances à l'aide de Nx et de ses riches fonctionnalités. Nous verrons comment configurer un serveur Nx, comment ajouter un plugin à un serveur existant et le concept d'un monorepo avec une visualisation pratique.

Si vous êtes un développeur cherchant à optimiser les applications et à créer des composants réutilisables efficacement entre les applications, cet article vous montrera comment faire évoluer rapidement vos applications et comment travailler avec Nx. Pour suivre, vous aurez besoin de connaissances de base sur le framework Next.js et TypeScript.

Qu'est-ce que Nx ?

Nx est un framework de construction open source qui vous aide à concevoir, tester et construire à n'importe quel scale — s'intégrant de manière transparente aux technologies et bibliothèques modernes, tout en fournissant une interface de ligne de commande (CLI), une mise en cache et une gestion des dépendances robustes. Nx propose aux développeurs des outils et des plug-ins CLI avancés pour les frameworks, les tests et les outils modernes.

Pour cet article, nous nous concentrerons sur le fonctionnement de Nx avec les applications Next.js. Nx fournit des outils standard pour tester et styliser vos applications Next.js, telles que Cypress, Storybook et les composants stylisés. Nx facilite un monorepo pour vos applications, en créant un espace de travail pouvant contenir le code source et les bibliothèques de plusieurs applications, vous permettant de partager des ressources entre les applications.

Pourquoi utiliser Nx ?

Nx fournit aux développeurs une quantité raisonnable de fonctionnalités prêt à l'emploi, y compris des passe-partout pour les tests de bout en bout (E2E) de votre application, une bibliothèque de styles et un monorepo. cette section.

  • Exécution de tâches basée sur des graphes
    Nx utilise une exécution de tâches distribuée basée sur des graphes et une mise en cache des calculs pour accélérer les tâches. Le système planifiera les tâches et les commandes à l'aide d'un système graphique pour déterminer quel nœud (c'est-à-dire l'application) doit exécuter chaque tâche. Cela gère l'exécution des applications et optimise le temps d'exécution de manière efficace.
  • Testing
    Nx fournit des outils de test préconfigurés pour les tests unitaires et les tests E2E.
  • Caching
    Nx stocke également le graphique du projet mis en cache. Cela lui permet de réanalyser uniquement les fichiers mis à jour. Nx garde une trace des fichiers modifiés depuis la dernière validation et vous permet de tester, créer et effectuer des actions uniquement sur ces fichiers ; cela permet une optimisation appropriée lorsque vous travaillez avec une grande base de code.
  • Graphique de dépendance
    Le graphique de dépendance visuel vous permet d'inspecter la façon dont les composants interagissent les uns avec les autres.
  • Le stockage dans le cloud
    Nx fournit également stockage en nuage et intégration GitHub, afin que vous puissiez partager des liens avec les membres de l'équipe pour consulter les journaux de projet.
  • Partage de code
    Créer une nouvelle bibliothèque partagée pour chaque projet peut être assez éprouvant. Nx élimine cette complication, vous permettant de vous concentrer sur les fonctionnalités principales de votre application. Avec Nx, vous pouvez partager des bibliothèques et des composants entre les applications. Vous pouvez même partager du code réutilisable entre vos applications front-end et back-end.
  • La prise en charge de monorepos
    Nx fournit un espace de travail pour plusieurs applications. Avec cette configuration, un référentiel GitHub peut héberger le code source de diverses applications sous votre espace de travail.

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

Nx pour les bibliothèques publiables

Nx vous permet de créer des bibliothèques publiables. Ceci est essentiel lorsque vous avez des bibliothèques que vous utiliserez en dehors du monorepo. Dans tous les cas où vous développez des composants d'interface utilisateur organisationnels avec l'intégration de Nx Storybook, Nx créera des composants publiables avec vos histoires. Les composants publiables peuvent compiler ces composants pour créer un ensemble de bibliothèques que vous pouvez déployer sur un registre externe. Vous utiliseriez l'option --publishable lors de la génération de la bibliothèque, contrairement à --buildablequi est utilisée pour générer des bibliothèques utilisées uniquement dans le monorepo. Nx ne déploie pas automatiquement les bibliothèques publiables ; vous pouvez invoquer la construction via une commande telle que nx build mylib (où mylib est le nom de la bibliothèque), qui produira alors un bundle optimisé dans le dist/mylib dossier qui peut être déployé dans un registre externe.

Nx vous donne la possibilité de créer un nouvel espace de travail avec Next.js comme préréglage, ou d'ajouter Next.js à un fichier existant workspace.

Pour créer un nouvel espace de travail avec Next.js comme préréglage, vous pouvez utiliser la commande suivante :

npx create-nx-workspace happynrwl
--preset=suivant 
--style=styled-components 
--appName=todo

Cette commande créera un nouvel espace de travail Nx avec une application Next.js nommée "todo" et avec styled-components comme bibliothèque de styles.

Ensuite, nous pouvons ajouter l'application Next.js à un espace de travail Nx existant avec la commande suivante :

npx nx g @nrwl/next:app

Création d'une application Next.js et Nx

Le plugin Nx pour Next.js comprend des outils et des exécuteurs pour exécuter et optimiser une application Next.js. Pour commencer, nous devons créer un nouvel espace de travail Nx avec next comme préréglage :

npx create-nx-workspace happynrwl 
--preset=suivant 
--style=composants-stylés 
--appName=todo

Le bloc de code ci-dessus générera un nouvel espace de travail Nx et l'application Next.js. Nous aurons une invite pour utiliser Nx Cloud. Pour ce tutoriel, nous sélectionnerons "Non", puis attendrons que nos dépendances s'installent. Une fois cela fait, nous devrions avoir une arborescence de fichiers semblable à celle-ci :

📦happynrwl
 📂applications
 ┣ todo
 ┣ 📂todo-e2e
 ┗ 📜.gitkeep
 📂libs
 node_modules
 📂outils
 📜.editorconfig
 .eslintrc.json
 📜.gitignore
 📜.prettierignore
 📜.prettierrc
 README.md
 babel.config.json
 jest.config.js
 jest.preset.js
 nx.json
 package-lock.json
 📜package.json
 tsconfig.base.json
 ┗ 📜workspace.json

Dans le dossier 📂appsnous aurons notre application Next.js « à faire », avec le test E2E préconfiguré pour l'application à faire. Tout est généré automatiquement avec le puissant outil CLI Nx.

Pour exécuter notre application, utilisez la commande npx nx serve todo. Une fois que vous avez terminé de servir l'application, vous devriez voir l'écran ci-dessous :

La page d'accueil générée par Nx pour une nouvelle application

Page par défaut Nx pour une nouvelle application. ( Grand aperçu)

Création de l'API

À ce stade, nous avons configuré l'espace de travail. La prochaine étape consiste à créer l'API CRUD que nous utiliserons sur l'application Next.js. Pour ce faire, nous utiliserons Express ; pour démontrer la prise en charge de monorepo, nous construirons notre serveur en tant qu'application dans l'espace de travail. Tout d'abord, nous devons installer le plugin Express pour Nx en exécutant cette commande :

npm install --save-dev @nrwl/express

Une fois cela fait, nous sommes prêts à configurer notre application Express dans l'espace de travail fourni . Pour générer une application Express, exécutez la commande ci-dessous :

npx nx g @nrwl/express:application --name=todo-api --frontendProject=todo

La commande nx g @nrwl/express : application générera une application Express à laquelle nous pourrons transmettre des paramètres de spécification supplémentaires ; pour spécifier le nom de l'application, utilisez le drapeau --name ; pour indiquer l'application frontale qui utilisera l'application Express, transmettez le nom d'une application dans notre espace de travail à --frontendProject. Quelques autres options sont disponibles pour une application Express. Lorsque cela sera fait, nous aurons une structure de fichiers mise à jour dans le dossier apps avec le dossier 📂todo-api ajouté.

📦happynrwl
 📂applications
 ┣ todo
 ┣ todo-api
 ┣ 📂todo-e2e
 ┗ 📜.gitkeep
 …

Le dossier todo-api est un passe-partout Express avec un fichier d'entrée main.ts.

/**
 * Ce n'est pas encore un serveur de production !
 * Ce n'est qu'un back-end minimal pour commencer.
 */
importer * comme express de 'express';
importer {v4 en tant que uuidV4} depuis 'uuid' ;

const app = express();
app.use(express.json()); // utilisé à la place de l'analyseur de corps

app.get('/api', (req, res) => {
  res.send({ message : 'Bienvenue sur todo-api !' });
});

const port = process.env.port || 3333 ;
const server = app.listen(port, () => {
  console.log(`Écoute sur http://localhost:${port}/api`);
});
server.on('erreur', console.erreur);

Nous allons créer nos itinéraires dans cette application. Pour commencer, nous allons initialiser un tableau d'objets avec deux paires clé-valeur, item et idjuste sous la déclaration d'application.

/**
 * Ce n'est pas encore un serveur de production !
 * Ce n'est qu'un back-end minimal pour commencer.
 */
importer * comme express de 'express';
importer {v4 en tant que uuidV4} depuis 'uuid' ;

const app = express();
app.use(express.json()); // utilisé à la place de l'analyseur de corps

let todoArray : Array<{ item: string; id: string }> = [
  { item: 'default todo', id: uuidV4() },
] ;
…

Ensuite, nous allons configurer la route pour récupérer toutes les listes de tâches sous app.get():

…
app.get('/api', (req, res) => {
  res.status(200).json({
    données : tableautodo,
  });
});
…

Le bloc de code ci-dessus renverra la valeur actuelle de todoArray. Par la suite, nous aurons des itinéraires pour créer, mettre à jour et supprimer des éléments à faire du tableau.

…

app.post('/api', (req, res) => {
  élément const : chaîne = req.body.item ;
  // Incrémente l'ID de l'élément en fonction de l'ID du dernier élément du tableau.
  let id: string = uuidV4();
  // Ajoute le nouvel objet au tableau
  todoArray.push({ élément, identifiant });
  res.status(200).json({
    message : « élément ajouté avec succès »,
  });
});
app.patch('/api', (req, res) => {
  // Valeur de l'élément mis à jour
  const updatedItem: string = req.body.updatedItem;
  // ID de la position à mettre à jour
  ID de const : chaîne = req.body.id ;
  // Recherche de l'index de l'ID
  const arrayIndex = todoArray.findIndex((obj) => obj.id === id);

  // Mettre à jour l'élément qui correspond à l'index
  todoArray[arrayIndex].item = updatedItem

  res.status(200).json({
    message : 'élément mis à jour avec succès',
  });
});

app.delete('/api', (req, res) => {
  // ID de la position à supprimer
  ID de const : chaîne = req.body.id ;
  // Mettre à jour le tableau et supprimer l'objet qui correspond à l'ID
  todoArray = todoArray.filter((val) => val.id !== id);
  res.status(200).json({
    message : 'élément supprimé avec succès',
  });
});

…

Pour créer un nouvel élément à faire, tout ce dont nous avons besoin est la valeur du nouvel élément sous forme de chaîne. Nous allons générer un ID en incrémentant l'ID du dernier élément du tableau sur le serveur. Pour mettre à jour un élément existant, nous transmettrons la nouvelle valeur de l'élément et l'ID de l'objet élément à mettre à jour ; sur le serveur, nous parcourions chaque élément avec la méthode forEach et mettrions à jour l'élément à l'endroit où l'ID correspond à l'ID envoyé avec la demande. Enfin, pour supprimer un élément du tableau, nous envoyons l'ID de l'élément à supprimer avec la demande ; puis, nous filtrons dans le tableau et renvoyons un nouveau tableau de tous les éléments ne correspondant pas à l'ID envoyé avec la demande, en attribuant le nouveau tableau à la variable todoArray.

Remarque : Si vous regardez dans le dossier de l'application Next.js, vous devriez voir un fichier proxy.conf.json avec la configuration ci-dessous :

{
  "/api": {
    "cible": "http://localhost:3333",
    "sécurisé": faux
  }
}

Cela crée un proxy, permettant à tous les appels d'API aux routes correspondant à /api de cibler le serveur todo-api.

Génération de pages Next.js avec Nx[19659044]Dans notre application Next.js, nous allons générer une nouvelle page, homeet un composant d'élément. Nx fournit un outil CLI pour nous permettre de créer facilement une page :

npx nx g @nrwl/next:page home

Lors de l'exécution de cette commande, nous aurons une invite pour sélectionner la bibliothèque de styles que nous voulons utiliser pour la page; pour cet article, nous sélectionnerons styled-components. Voilà ! Notre page est créée. Pour créer un composant, exécutez npx nx g @nrwl/next:component todo-item ; cela créera un dossier component avec le composant todo-item.

Consommation API dans l'application Next.js

Dans chaque élément à faire, nous aurons deux boutons , pour modifier et supprimer la tâche. Les fonctions asynchrones effectuant ces actions sont transmises en tant qu'accessoires à partir de la page d'accueil.

…
interface d'exportation TodoItemProps {
  updateItem(id : string, updatedItem : string) : Promise ;
  deleteItem(id : chaîne) : Promise ;
  fetchItems() : Promesse ;
  élément : chaîne ;
  identifiant : chaîne ;
}
export const FlexWrapper = styled.div`
  largeur : 100 % ;
  affichage : flexible ;
  justifier-contenu : espace-entre ;
  align-items: center;
  border-bottom : 1px solide #ccc ;
  rembourrage en bas : 10px ;
  marge supérieure : 20 px ;
  @media all and (max-width: 470px) {
    flex-direction : colonne ;
    saisir {
      largeur : 100 % ;
    }
    bouton {
      largeur : 100 % ;
    }
  }
`;

fonction d'exportation TodoItem (accessoires : TodoItemProps) {
  const [isEditingItem, setIsEditingItem] = useState(false);
  const [item, setNewItem] = useState(null);

  revenir (
    
       setNewItem(target.value)}
      />
      {!isEditingItem && }
      {isEditingItem && }
      
    
  );
}

Pour la fonctionnalité de mise à jour, nous avons une entrée qui est désactivée lorsque l'état isEditingItem est false. Une fois le bouton « Modifier » cliqué, il bascule l'état isEditingItem à true et affiche le bouton « Mettre à jour ». Ici, le composant d'entrée est activé et l'utilisateur peut entrer une nouvelle valeur ; lorsque le bouton « Mettre à jour » est cliqué, il appelle la fonction updateItem avec les paramètres transmis, et il bascule isEditingItem à false.

In le composant de page homenous avons les fonctions asynchrones effectuant l'opération CRUD.

 …
  const [items, setItems] = useState<Array<{ item: string; id: string }>>([]);
  const [newItem, setNewItem] = useState('');
  const fetchItems = async () => {
    essayer {
      données const = wait fetch('/api/fetch');
      const res = wait data.json();
      setItems(res.data);
    } catch (erreur) {
      console.log(erreur);
    }
  } ;
  const createItem = async (élément : chaîne) => {
    essayer {
      const data = wait fetch('/api', {
        méthode : 'POSTER',
        corps : JSON.stringify({ élément }),
        en-têtes : {
          « Type de contenu » : « application/json »,
        },
      });
    } catch (erreur) {
      console.log(erreur);
    }
  } ;
  const deleteItem = async (id : chaîne) => {
    essayer {
      const data = wait fetch('/api', {
        méthode : 'SUPPRIMER',
        corps : JSON.stringify({ id }),
        en-têtes : {
          « Type de contenu » : « application/json »,
        },
      });
      const res = wait data.json();
      alert(res.message);
    } catch (erreur) {
      console.log(erreur);
    }
  } ;
  const updateItem = async (id : string, updatedItem : string) => {
    essayer {
      const data = wait fetch('/api', {
        méthode : 'PATCH',
        corps : JSON.stringify({ id, updatedItem }),
        en-têtes : {
          'Type de contenu' : 'application/json',
        },
      });
      const res = wait data.json();
      alert(res.message);
    } catch (erreur) {
      console.log(erreur);
    }
  } ;
  useEffect(() => {
    fetchItems();
  }, []);
…

Dans le bloc de code ci-dessus, nous avons fetchItemsqui renvoie todoArray depuis le serveur. Ensuite, nous avons la fonction createItemqui prend une chaîne ; le paramètre est la valeur du nouvel élément à faire. La fonction updateItem prend deux paramètres, l'ID de l'élément à mettre à jour et la valeur updatedItem. Et la fonction deleteItem supprime l'élément correspondant à l'ID qui est transmis.

Pour rendre l'élément à faire, nous mappons via l'état items :

 …
revenir (
    
      

Bienvenue à la maison !

{items.length > 0 && items.map((val) => ( ))}
{ e.preventDefault(); wait createItem(newItem); //Nettoyer le nouvel élément setNewItem(''); attendre fetchItems(); }} > setNewItem(target.value)} placeholder="Ajouter un nouvel élément…" />
); …

Notre serveur et notre frontal sont maintenant configurés. Nous pouvons servir l'application API en exécutant npx nx serve todo-apiet pour l'application Next.js, nous exécutons npx nx serve todo. Cliquez sur le bouton "Continuer" et vous verrez une page avec l'élément à faire par défaut affiché.

 La page des éléments à faire de l'application, avec la liste des tâches par défaut sur le serveur.

Les éléments à faire de l'application page. ( Grand aperçu)

Nous avons maintenant une application Next.js et Express fonctionnant ensemble dans un espace de travail.

Nx dispose d'un autre outil CLI qui nous permet d'afficher le graphique de dépendance de notre application dans notre exécution de terminal. Exécutez npx nx dep-graphet nous devrions voir un écran similaire à l'image ci-dessous, représentant le graphique de dépendance de notre application.

Graphique de dépendance montrant la relation entre les applications sur l'espace de travail

Application dep -graphique. ( Grand aperçu)

Autres commandes CLI pour Nx

  • nx list
    Répertorie les plug-ins Nx actuellement installés.
  • nx migrate last
    Met à jour les packages dans package.json vers la dernière version.
  • nxaffected
    Effectue l'action uniquement sur les applications affectées ou modifiées.
  • nx run-many --target serve --projects todo-api,todo
    Exécute la commande cible sur tous les projets répertoriés.

Conclusion

En tant qu'aperçu général de Nx, cet article a couvert ce que Nx propose et comment cela nous facilite le travail. Nous avons également expliqué comment configurer une application Next.js dans un espace de travail Nx, ajouter un plug-in Express à un espace de travail existant et utiliser la fonction monorepo pour héberger plusieurs applications dans notre espace de travail.

Vous trouverez le code source complet. dans le dépôt GitHub. Pour plus d'informations sur Nx, consultez la documentation ou la Nx documentation pour Next.js.

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




Source link