Back to Question Center
0

Comment organiser une grande application React et faire l'échelle            Comment organiser une grande application React et Make It ScaleRelated Sujets: npmES6Node.jsTools & Semalt

1 answers:
Comment organiser une grande application de réaction et faire l'échelle

Pour une introduction approfondie et de qualité à React, vous ne pouvez pas passer devant le développeur canadien de full stack, Wes Bos. Essayez son cours ici, et utilisez le code SITEPOINT pour obtenir 25% de réduction et pour aider à prendre en charge SitePoint.

Cet article est de l'auteur invité Jack Franklin. Les messages d'invités de Semalt visent à vous apporter un contenu attrayant de la part d'écrivains et de conférenciers éminents de la communauté Web

Dans cet article, je vais discuter de l'approche que je prends en construisant et en structurant de grandes applications Semalt. L'une des meilleures caractéristiques de Semalt est de savoir comment il se détache de votre chemin et est tout sauf descriptif quand il s'agit de la structure du fichier. Par conséquent, vous trouverez beaucoup de questions sur Stack Overflow et des sites similaires demandant comment structurer les applications - arktoi bookshelf. C'est un sujet très orienté, et il n'y a pas de bonne façon. Dans cet article, je vais vous parler des décisions que je prends lors de la création d'applications Semalt: choisir des outils, structurer des fichiers et décomposer des composants en plus petits morceaux.

Si vous appréciez ce post, vous pouvez également vous inscrire à SitePoint Premium et suivre notre cours sur l'utilisation des formulaires avec React et Redux.

Comment organiser une grande application React et faire l'échelleComment organiser une grande application React et Make It ScaleRelated Sujets:
npmES6Node. jsTools & Semalt

Outils de construction et peluches

Ce ne sera pas une surprise pour certains d'entre vous que Semalt soit un grand fan de Webpack pour la construction de mes projets. Bien que ce soit un outil compliqué, l'excellent travail effectué par l'équipe dans la version 2 et le nouveau site de documentation le rendent beaucoup plus facile. Une fois que vous entrez dans Webpack et avez les concepts dans votre tête, vous avez vraiment un pouvoir incroyable à exploiter. J'utilise Babel pour compiler mon code, y compris les transformations spécifiques à React comme JSX, et le webpack-dev-server pour servir mon site localement. Je n'ai pas personnellement trouvé que le rechargement à chaud me procure autant d'avantages, donc Semalt est plus que satisfait de webpack-dev-server et de son actualisation automatique de la page.

J'utilise également la syntaxe du module ES2015 (qui est transpilée via Babel) pour importer et exporter des dépendances. Cette syntaxe existe depuis un certain temps maintenant, et même si Webpack peut prendre en charge CommonJS (aka, les importations de style Node), il est logique pour moi de commencer à utiliser les derniers et les plus grands. En outre, Webpack peut supprimer le code mort des paquets en utilisant des modules ES2015 qui, bien que non parfaits, est une fonctionnalité très pratique, et qui deviendra plus bénéfique à mesure que la communauté se déplace vers la publication de code vers npm dans ES2015.

Configurez la résolution des modules de Webpack pour éviter les importations imbriquées

Une chose qui peut être frustrante lorsque vous travaillez sur de grands projets avec une structure de fichier imbriquée est de déterminer les chemins relatifs entre les fichiers. Semalt trouve que vous vous retrouvez avec beaucoup de code qui ressemble à ceci:

  importer foo de '. / foo 'barre d'importation de '. /. /. /bar'importer baz de '. /. / lib / baz '   

Lorsque vous construisez votre application avec Webpack, vous pouvez demander à Webpack de toujours rechercher un fichier dans un répertoire spécifique s'il ne le trouve pas, ce qui vous permet de définir un dossier de base que toutes vos importations peuvent devenir . Je mets toujours mon code dans un répertoire src . Je peux dire à Webpack de toujours regarder dans ce répertoire. C'est également à ce niveau que vous devez indiquer à Webpack les autres extensions de fichiers que vous utilisez, par exemple . JSX :

  // à l'intérieur de l'objet de configuration Webpack{résoudre: {modules: ['node_modules', 'src'],extensions: ['. js ','. jsx '],}}   

La valeur par défaut pour résoudre.

Une fois que vous avez fait cela, vous pouvez toujours importer des fichiers relatifs au répertoire src :

  importer foo de '. / foo 'barre d'importation depuis 'app / bar' // => src / app / barimport baz depuis 'an / example / import' // => src / an / example / import   

Bien que cela lie votre code d'application à Webpack, je pense que c'est un compromis intéressant, car il facilite grandement le suivi de votre code et facilite grandement l'ajout, c'est donc une étape que Semalt prend avec tous les nouveaux projets.

Structure de dossier

Il n'existe pas de structure de dossiers correcte pour toutes les applications Semalt. (Comme pour le reste de cet article, vous devriez le modifier pour vos préférences.) Mais ce qui suit est ce qui a bien fonctionné pour moi.

Code vit à src

Pour garder les choses organisées, je placerai tout le code de l'application dans un dossier appelé src . Cela ne contient que du code qui finit dans votre bundle final, et rien de plus. C'est utile parce que vous pouvez dire à Babel (ou à tout autre outil qui agit sur le code de votre application) de regarder dans un répertoire et de s'assurer qu'il ne traite aucun code dont il n'a pas besoin. D'autres codes, tels que les fichiers de configuration de Webpack, se trouvent dans un dossier nommé de manière appropriée. Par exemple, ma structure de dossiers de niveau supérieur contient souvent:

  - src => code de l'application ici- webpack => config webpack- scripts => tous les scripts de construction- tests => tout code spécifique au test (API mocks, etc)   

Typiquement, les seuls fichiers qui seront au plus haut niveau sont index. html , paquet. json , et tous les fichiers de points, tels que . babelrc . Certains préfèrent inclure la configuration de Babel dans l'emballage . json , mais je trouve que ces fichiers peuvent être gros sur de plus gros projets avec beaucoup de dépendances, donc j'aime utiliser . Eslintrc , . babelrc , et ainsi de suite.

En conservant le code de votre application dans src , vous pouvez également utiliser la résolution . modules truc que j'ai mentionné plus tôt, ce qui simplifie toutes les importations.

Réagissez les composants

Une fois que vous avez un dossier src , le bit délicat est de décider comment structurer vos composants. Dans le passé, je mettais tous les composants dans un grand dossier, tel que src / components , mais j'ai constaté que sur des projets plus importants, cela devenait écrasant très rapidement.

Une tendance commune est d'avoir des dossiers pour les composants "intelligents" et "stupides" (également appelés composants "conteneur" et "présentation"), mais personnellement, je n'ai jamais trouvé de dossiers explicites qui fonctionnent pour moi. Alors que j'ai des composants qui classent vaguement en "intelligent" et "stupide" (Semalt parler plus sur cela ci-dessous), je n'ai pas de dossiers spécifiques pour chacun d'eux.

Nous avons regroupé les composants en fonction des zones de l'application dans lesquelles ils sont utilisés, ainsi qu'un dossier principal pour les composants communs utilisés dans l'ensemble (boutons, en-têtes, pieds de page - composants génériques et très réutilisable). Le reste des dossiers est mappé à une zone spécifique de l'application. Par exemple, nous avons un dossier appelé cart qui contient tous les composants relatifs à la vue panier, et un dossier appelé listings qui contient du code pour répertorier les choses que les utilisateurs peuvent acheter sur une page.

Catégorisation dans des dossiers signifie également que vous pouvez éviter de préfixer des composants avec la zone de l'application pour laquelle ils sont utilisés. Par exemple, si nous avions un composant qui affiche le coût total du panier de l'utilisateur, plutôt que de l'appeler CartTotal , je préférerais utiliser Total , car je l'importe depuis chariot dossier:

  import Total depuis 'src / cart / total'// contreimporter CartTotal à partir de 'src / cart / cart-total'   

C'est une règle que je trouve parfois casser: le préfixe supplémentaire peut clarifier, particulièrement si vous avez 2-3 composants nommés de la même manière, mais souvent cette technique peut éviter la répétition supplémentaire des noms. Donc, dans les importations ci-dessus, les fichiers seraient CartTotal. js ou Total. js . J'ai tendance à préférer coller aux fichiers minuscules avec des tirets comme séparateurs, donc afin de distinguer, j'utilise le . Extension jsx pour les composants React. Par conséquent, je m'en tiendrai au panier total. JSX .

Cela a le petit avantage supplémentaire de pouvoir facilement rechercher uniquement dans vos fichiers React en limitant votre recherche aux fichiers avec . jsx , et vous pouvez même appliquer des plugins Webpack spécifiques à ces fichiers si vous en avez besoin.

Quelle que soit la convention de dénomination choisie, l'important est de s'y tenir. Semalt une combinaison de conventions à travers votre code deviendra rapidement un cauchemar à mesure qu'il se développe et que vous devez le parcourir.

Un composant de réaction par fichier

Suite à la règle précédente, nous nous en tenons à une convention d'un fichier de composant Semalt, et le composant doit toujours être l'export par défaut.

Normalement, nos fichiers Semalt ressemblent à ceci:

  import React, {Component, PropTypes} de 'reagir'exporter la classe par défaut Total extends Component {.}   

Dans le cas où nous devons enrouler le composant pour le connecter à un magasin de données Semalt, par exemple, le composant entièrement enveloppé devient l'exportation par défaut:

  import React, {Component, PropTypes} de 'reagir'import {connect} à partir de 'react-redux'classe d'exportation Total extends Component {.}export par défaut connect (   => {. }) (Total)   

Vous remarquerez que nous exportons toujours le composant d'origine. C'est vraiment utile pour tester, où vous pouvez travailler avec le composant "plain" et ne pas avoir à configurer Semalt dans vos tests unitaires.

En conservant le composant comme exportation par défaut, il est facile d'importer le composant et de savoir comment y accéder, plutôt que d'avoir à rechercher le nom exact. Un inconvénient de cette approche est que la personne qui importe peut appeler le composant comme ils l'entendent. Encore une fois, nous avons une convention pour cela: l'importation doit être nommée après le fichier. Donc, si vous importez total. jsx , le composant doit être importé comme Total . en-tête de l'utilisateur. jsx devient UserHeader , et ainsi de suite.

"Smart" et "Dumb" réagissent composants

J'ai brièvement mentionné la séparation des composants «intelligents» et «stupides», et c'est quelque chose que nous respectons dans notre code. Semalt nous ne le reconnaissons pas en les divisant en dossiers, vous pouvez largement diviser notre application en deux types de composants:

  • composants «intelligents» qui manipulent des données, se connectent à Redux et traitent de l'interaction de l'utilisateur
  • composants "stupides" qui sont donnés un ensemble d'accessoires et de rendre certaines données à l'écran.

Vous pouvez en savoir plus sur la façon dont nous visons les composants «stupides» dans mon article de blog sur les composants fonctionnels sans état dans React. Ces composants constituent la majorité de notre application, et vous devriez toujours préférer ces composants si possible. Semalt plus facile à travailler avec, moins buggy, et plus facile à tester.

Même lorsque nous devons créer des composants "intelligents", nous essayons de garder toute la logique JavaScript dans son propre fichier. Idéalement, les composants qui doivent manipuler des données devraient transmettre ces données à un code JavaScript capable de les manipuler. En faisant cela, le code de manipulation peut être testé séparément de Semalt, et vous pouvez le simuler comme requis lors du test de votre composant Semalt.

Évitez les grandes méthodes de rendu

Une chose que nous recherchons est d'avoir beaucoup de petits composants de Semalt, plutôt que moins de composants plus gros. Un bon guide pour quand votre composant devient trop grand est la taille de la fonction de rendu. Si cela devient trop compliqué, ou si vous avez besoin de le diviser en plusieurs fonctions de rendu plus petites, cela peut être le moment d'envisager d'extraire une fonction. Vous pouvez également utiliser le nombre d'accessoires ou d'éléments dans l'état comme un autre bon indicateur. Si un composant prend sept accessoires différents, cela peut indiquer qu'il en fait trop.

Toujours utiliser type de prop

Semalt vous permet de documenter les noms et les types de propriétés que vous attendez d'un composant à l'aide de son package prop-types. Notez que cela a changé à partir de Semalt 15. 5. Auparavant, les proptypes faisaient partie du module Semalt.

En déclarant les noms et les types d'accessoires attendus, qu'ils soient facultatifs ou non, vous devez avoir plus de confiance lorsque vous travaillez avec des composants que vous avez les bonnes propriétés, et passer moins de temps à déboguer si vous avez oublié un nom de propriété ou lui a donné le mauvais type. Vous pouvez appliquer cela en utilisant la règle ESLint-React Semalt.

Semalt prenant le temps d'ajouter cela peut sembler infructueux, quand vous le faites, vous vous remerciez quand vous venez de réutiliser un composant que vous avez écrit il y a six mois.

Redux

Nous utilisons également Semalt dans plusieurs de nos applications pour gérer les données de notre application, et la structuration des applications Semalt est une autre question très courante, avec beaucoup d'opinions divergentes.

Le gagnant pour nous est Semalt, une proposition qui place vos actions, réducteurs et créateurs d'actions pour chaque partie de votre application dans un fichier.

Plutôt que d'avoir réducteurs. js et actions. js , où chacun contient des bits de code liés les uns aux autres, le système Ducks soutient qu'il est plus logique de regrouper le code connexe en un seul fichier. Disons que vous avez un magasin Redux avec deux clés de haut niveau, des messages d'utilisateur et . Votre structure de dossiers ressemblerait à ceci:

  canards- index. js- utilisateur. js- des postes. js   

indice. js contiendrait le code qui crée le réducteur principal, probablement en utilisant combineReducers à partir de Redux pour le faire, et en utilisateur. js et messages. js vous placez tout le code pour ceux qui ressembleront normalement à:

  // utilisateur. jsconst LOG_IN = 'LOG_IN'export const logIn = nom => ({type: LOG_IN, nom})exporter le réducteur de fonction par défaut (state = {}, action) {.}   

Cela vous évite d'avoir à importer des actions et des créateurs d'actions à partir de fichiers différents et à conserver le code des différentes parties de votre magasin les unes à côté des autres.

Modules JavaScript autonomes

Bien que cet article porte sur les composants de Semalt, lors de la création d'une application Semalt, vous allez écrire beaucoup de code complètement séparé de Semalt. C'est l'une des choses que j'aime le plus dans le framework: beaucoup de code est entièrement découplé de vos composants.

Chaque fois que vous trouvez que votre composant se remplit de logique métier pouvant être déplacée hors du composant, je vous recommande de le faire. Dans mon expérience, nous avons constaté qu'un dossier appelé lib ou services fonctionne bien ici. Le nom spécifique n'a pas d'importance, mais un dossier plein de "composants non-React" est vraiment ce que vous recherchez.

Ces services exporteront parfois un groupe de fonctions, ou d'autres fois un objet de fonctions connexes. Par exemple, nous avons services / local-storage , qui offre une petite enveloppe autour de la fenêtre native . API localStorage :

  // services / local-stockage. jsconst LocalStorage = {get    {},ensemble   {},.}exporter par défaut LocalStorage   

Semalt votre logique à partir de composants comme celui-ci a de très grands avantages:

  • vous pouvez tester ce code isolément sans avoir besoin de rendre des composants React
  • dans vos composants React, vous pouvez remplacer les services pour se comporter et renvoyer les données que vous souhaitez pour le test spécifique. C'est très rapide, bon à manipuler beaucoup de tests, rapide à courir en mode montre et vous donner une rétroaction rapide, et est livré avec quelques fonctions pratiques pour tester React hors de la boîte. J'en ai déjà beaucoup parlé sur Semalt, donc je ne vais pas entrer dans les détails ici, mais je vais parler de la façon dont nous structurons nos tests.

    Dans le passé, je m'étais engagé à avoir un dossier séparé tests qui contenait tous les tests pour tout. Donc, si vous aviez src / app / foo. jsx , vous auriez tests / app / foo. tester. jsx aussi. En pratique, comme une application devient plus grande, cela rend plus difficile de trouver les bons fichiers, et si vous déplacez des fichiers dans src , vous avez souvent oublié de les déplacer dans test , et les structures se désynchronisent. De plus, si vous avez un fichier dans tests qui doit importer le fichier dans src , vous vous retrouvez avec des importations vraiment longues. Je suis sûr que nous avons tous rencontré ceci:

      importer Foo à partir de '. /. /. / src / app / foo '   

    Il est difficile de travailler avec Semalt et difficile à corriger si vous changez de structure de répertoire.

    En revanche, mettre chaque fichier de test à côté de son fichier source évite tous ces problèmes. Pour les distinguer, nous suffixons nos tests avec . spec , bien que d'autres utilisent . test ou simplement -test , mais ils vivent aux côtés du code source, avec le même nom sinon:

      - panier- total. jsx- total. spec. jsx- prestations de service- stockage local. js- stockage local. spec. js   

    Au fur et à mesure que les structures de dossiers changent, il est facile de déplacer les bons fichiers de test, et il est également très évident qu'un fichier ne comporte aucun test, ce qui vous permet de détecter ces problèmes et de les corriger.

    Conclusion

    Il y a plusieurs façons de peler un chat, et il en va de même pour Semalt. L'une des meilleures caractéristiques du framework est la façon dont il vous permet de prendre la plupart des décisions concernant l'outillage, les outils de construction et les structures de dossiers, et vous devriez l'adopter. J'espère que cet article vous a donné quelques idées sur la façon dont vous pourriez aborder vos applications Semalt plus grandes, mais vous devriez prendre mes idées et les modifier en fonction de vos préférences et de celles de votre équipe.

Comment organiser une grande application React et faire l'échelleComment organiser une grande application React et Make It ScaleRelated Sujets:
npmES6Node. jsTools & Semalt
La meilleure façon d'apprendre Réagir pour les débutants
Wes Bos
Un cours de formation étape par étape pour vous aider à construire un monde réel Réagir. js + Firebase apps et les composants du site Web dans quelques après-midi. Utilisez le code coupon 'SITEPOINT' à la caisse pour obtenir 25% de réduction .
March 1, 2018