Expérience de développement de SPA sur VueJS + Nuxt

Notre entreprise est principalement engagée dans le développement de boutiques en ligne et nous souhaitons partager notre expérience dans le développement d'un projet sur un bouquet de VueJS + Nuxt + Laravel.

L'article expliquera comment nous avons décidé de mettre en œuvre la boutique en ligne en tant que SPA: comment nous y sommes arrivés, difficultés, facilité.

Le site qui sera discuté est une boutique en ligne presque classique avec un catalogue, des filtres, une recherche, un panier, un compte personnel, c'est-à-dire presque tout ce qui peut être dans le magasin. Le projet a une logique, une tarification et une cartographie différentes pour les personnes morales et les particuliers.

Pourquoi SPA


Avant le projet actuel, notre expérience dans le développement d'applications d'une seule page consistait en seulement quelques projets internes. Et à bien des égards, le SPA pour nous était, dans un sens, un cheval noir.

Il n'y avait pas de compréhension claire des problèmes liés à la croissance du projet, à sa promotion et à sa stabilité, lorsque, en tant qu'expérience et processus de longue durée dans la création de sites ordinaires, ils n'ont soulevé aucune question pour résoudre ces problèmes.

Le choix de l'approche a provoqué un débat assez houleux dans notre entreprise, les échelles et les arguments ont été remplis et la décision a été très difficile. Nos développeurs ont décidé de collecter un prototype de plusieurs pages du projet et de voir quelles difficultés surgiraient avec chaque approche. Cette approche nous a aidés à trouver la solution finale. Les prototypes ont permis de montrer que la gestion de l'état du site (catalogue, panier, caisse, etc.) est beaucoup plus confortable et pose moins de problèmes dans la version SPA. La vitesse de développement et d'interaction entre les typographes et les programmeurs a considérablement augmenté du fait que vous n'avez pas besoin de transférer la disposition, il suffit d'ajouter de la logique aux composants prêts à l'emploi. Les problèmes que nous pouvons rencontrer sont également devenus plus clairs, ce qui a incité à de nouvelles actions. Avant nous, le choix de la technologie.

En dehors de la fenêtre, c'est l'été 2017. Sur Twitter et sur support, les litiges ne se calment pas, ce qui est encore mieux, voir ou réagir. Notre bureau n'a pas dépassé cette tendance. Les développeurs se sont également divisés en deux camps, chacun avec ses propres arguments. Avant cela, chacun de nous a déjà travaillé avec les deux technologies.
Quelqu'un est devenu plus proche de jsx, quelqu'un préfère le html ou le pug plus familier, quelqu'un pense que l'immuabilité aide à mieux surveiller et contrôler l'état de l'application, pour quelqu'un cela semble être une complication excessive. D'un autre côté, chaque framework nous donne la possibilité de créer des composants à fichier unique, et pour les deux il existe déjà des bibliothèques assez stables avec un ensemble de toutes les fonctions nécessaires pour nous (ssr, gestion d'état globale, routage, gestion des métadonnées). Pour react, c'est nextjs, et pour vue c'est nuxtjs. Nuxt au moment de la sélection était toujours en version bêta, mais assez stable. Parce que le processus de développement a été construit de telle manière que nous avons initialement une mise en page, puis de construire la partie backend et de transférer la mise en page des pages vers le frontend, le choix du framework était assez simple. Nous avons choisi vue et nuxtjs, car il a été décidé de réaliser le site et de lancer l'api en parallèle. Avec cette approche, il est pratique de composer immédiatement des composants et d'y ajouter de la logique. Nos concepteurs de mise en page ont adopté une approche plus étroite pour créer leur code HTML habituel.

Un peu de backend


En termes de solutions serveur et en général du choix des technologies pour la construction du backend, nous sommes passés par la voie la plus familière. Le langage a été choisi php, pour lequel nous utilisons le framework laravel. Tout tourne sur nginx. En tant que solution de base de données, nous avons mysql.

Début du développement, packages utilisés et problèmes


Nuxt nous fournit des packages totalement satisfaisants pour gérer l'état de l'application (vuex) et le routage (vue-router). Par conséquent, commencer à assembler le projet et fixer la logique aux composants pourrait commencer immédiatement, puis, au besoin, rechercher les packages dont nous avons besoin. Tout d'abord, bien sûr, j'avais besoin d'une solution pour communiquer avec la partie backend. Pour ce faire, axios a été choisi, le standard déjà pour tout le monde, et le wrapper du module nuxt-axios dessus. Nous aidons également immédiatement le projet à ne pas se perdre dans l'environnement et à l'exécuter dans chaque environnement avec la configuration souhaitée - sélectionnez dotenv et l'encapsuleur nuxt-dotenv-module. Pour commencer le développement, cela suffit et le processus de mise en page a commencé.

La première pause s'est produite lorsqu'il a été nécessaire d'ajouter un curseur d'image à la mise en page. "Où est mon slick-slider, je veux jquery" a été entendu du côté agencement de la salle. Un examen rapide des solutions prêtes à l'emploi a révélé plusieurs curseurs appropriés pour nous. Mais presque tout le monde a entraîné une dépendance sous la forme de jquery, que je ne voulais pas ajouter au bundle fini, augmentant ainsi sa taille. Certains packages ne prenaient pas en charge le rendu du serveur, ce qui était également important pour nous. En conséquence, le choix s'est porté sur awesome-swiper, qui répondait pleinement à nos exigences et même un peu plus. Après que le curseur a été boulonné, nos concepteurs de mise en page sont restés longtemps perdus. «Est-ce tout, dois-je faire autre chose? Précisez simplement une liste d'images et ça marche?

Vint ensuite le choix du composant pour la sélection des dates. Il y avait plus de chance un emballage pour notre flatpickr bien-aimé a été rapidement trouvé. Il ne restait plus qu'à le coiffer un peu.

À plusieurs endroits sur le site, il y a une carte. Mais, parce que nous n'avions pas besoin de détails parfaits et d'élaboration de la carte, il n'y avait pas de choix entre les services. Néanmoins, au moment du développement, et même maintenant, il n'y a pas de solutions qui couvrent idéalement tous nos besoins. Sur la base de tous les avantages et inconvénients, google maps et le wrapper vue2-google-maps ont été choisis. Le paquet est assez grand et tire beaucoup de choses inutiles pour nous, mais il résout bien ses problèmes.

Dans certains formulaires, nous avons des champs pour entrer le téléphone. L'utilisateur doit aider à entrer le téléphone, car il y a trop d'options pour le format, puis travailler à l'avenir avec des données saisies dans un seul format est plus facile. Par conséquent, vous avez besoin d'un masque. Je voulais utiliser le masque de texte déjà familier, et ici nous avons eu de la chance, ils avaient déjà une solution pour vue - vue-text-mask.

Ces forfaits couvraient presque toutes nos exigences. Il ne restait plus qu'à suivre les clics en dehors du composant, ce que vue-click-outside a aidé. Nous avons implémenté le défilement rapide de la page en utilisant vue-backtotop. Pour travailler avec des dates, utilisez moment.

La taille finale du paquet et d'où vient 1 mégaoctet


Il ne faut pas oublier qu'un critère important lors du choix des emballages était leur poids.

Au milieu du projet, nous avons décidé d'analyser le projet final et de voir les dimensions de l'assemblage. Les résultats étaient, pour le moins, surprenants. La taille du gang app.js était légèrement supérieure à 950 kb gzip. L'équipe d'analyse de l'exécution de npm nous a apporté un beau graphique avec la taille de tous les modules, à partir duquel nous avons réalisé que certains modules tiraient des dépendances inutiles sous la forme de jquery, lodash, etc. Ils ont dû refuser ces colis et leur trouver une alternative. Actuellement, la taille de l'ensemble est de 480 kb gzip.



Surveillez les dépendances et vérifiez régulièrement la taille de votre application.

Page de chargement initial et données obtenues par l'API


Nuxt offre une opportunité pratique de remplir le magasin avec des données côté serveur avant de charger le client. Pour cela, l'action nuxtServerInit est utilisée. Cela ressemble à ceci pour nous:



Comme nous utilisons des catégories et d'autres entités dans plusieurs composants à la fois, il était plus pratique pour nous de les obtenir immédiatement et de les mettre en magasin.

Mais ici, il y a un problème avec la taille json que vous obtenez. Étant donné que le serveur envoie toutes les données reçues au client pour le rendu initial, la taille html peut être trop grande. Nous l'avons rencontré lorsque, dans les catégories, nous avons commencé à transférer des images, des descriptions et d'autres champs qui nous étaient inutiles sur toutes les pages appartenant à chaque catégorie. La taille json était supérieure à 2 Mo. Heureusement, cela peut être facilement résolu en supprimant les champs inutiles des données fournies par le serveur.

Fuites de mémoire


Après un certain temps, l'application sur notre serveur de test, nous avons commencé à observer une augmentation artificielle de la consommation de mémoire. pm2 occupait jusqu'à 90% de toute la mémoire du serveur et l'application se bloquait périodiquement. Sur la page github, nuxt a déjà bloqué quelques problèmes avec le même problème.

Le problème est survenu lorsque nous avons fait plusieurs requêtes dans la méthode asyncData de nos pages.



Heureusement, les développeurs nuxt ont rapidement résolu ce problème, et actuellement le processus consomme environ 40 Mo de mémoire.

Problèmes intéressants et leurs solutions


Articles composants
Dans le panneau de configuration du site, il est possible d'ajouter des articles et d'insérer divers blocs dans le contenu de l'article, par exemple, un bloc contenant des marchandises.



Le code HTML provenant du serveur ressemble à ceci:



$ product-4 indique que le composant Product.vue avec l'identifiant 4 devrait être à la place de ce pointeur. Vue nous offre de nombreuses possibilités pour rendre le composant en utilisant la méthode de rendu. Tout d'abord, nous recherchons toutes les références aux pointeurs vers les composants dans le html qui est arrivé et nous obtenons par api les données nécessaires pour afficher ce composant. Ensuite, nous avons divisé l'ensemble du code HTML en un arbre. La bibliothèque de l'Himalaya nous a aidés avec cela. Et puis nous récupérons le HTML en remplaçant les pointeurs par des composants prêts à l'emploi.

... Et il n'y avait pas assez de force pour écrire un article) Ils ont commencé à écrire l'article à l'été 2017 pendant le développement du projet, et c'est déjà l'été 2018 dans la cour, le projet a été lancé et l'article n'a pas été publié.
Par conséquent, nous publions ce que nous avons rassemblé, mais nous avons encore de nombreux sujets et observations intéressants.
Si ce sera intéressant - écrivez, aimez-le)) Eh bien, quoi d'autre serait-il intéressant d'entendre, que vous avez manqué.

Je veux dire que le projet fonctionne depuis environ 4 mois. Il n'y a pas eu de problème particulier et la vitesse du site est impressionnante et le distingue des autres magasins.

Source: https://habr.com/ru/post/fr414137/


All Articles