Experiência de desenvolvimento de SPA no VueJS + Nuxt

Nossa empresa está envolvida principalmente no desenvolvimento de lojas on-line e queremos compartilhar nossa experiência no desenvolvimento de um projeto em um monte de VueJS + Nuxt + Laravel.

O artigo discutirá como decidimos implementar a loja online como um SPA: como chegamos a isso, dificuldades, facilidade.

O site que será discutido é uma loja on-line quase clássica, com um catálogo, filtros, pesquisa, cesta, conta pessoal, ou seja, quase tudo o que pode estar na loja. O projeto possui uma lógica, preço e mapeamento diferentes para pessoas jurídicas e indivíduos.

Porquê SPA


Antes do projeto atual, nossa experiência no desenvolvimento de aplicativos de página única consistia em apenas alguns projetos internos. E, sob muitos aspectos, o SPA para nós era, em certo sentido, um azarão.

Não havia um entendimento claro dos problemas associados ao crescimento do projeto, sua promoção e estabilidade seo, quando, como experiência e processos de longa duração na criação de sites comuns, eles não levantaram nenhuma dúvida na solução desses problemas.

A escolha da abordagem causou um debate bastante acalorado em nossa empresa, tanto as escalas quanto os argumentos foram preenchidos e a decisão foi muito difícil. Nossos desenvolvedores decidiram coletar um protótipo de várias páginas do projeto e ver quais dificuldades surgiriam em cada abordagem. Essa abordagem nos ajudou com a solução final. Os protótipos ajudaram a mostrar que o gerenciamento do estado do site (catálogo, cesta, caixa, etc.) é muito mais confortável e causa menos problemas na versão do SPA. A velocidade de desenvolvimento e interação entre tipógrafos e programadores aumentou significativamente devido ao fato de você não precisar transferir o layout, basta adicionar lógica aos componentes prontos. Os problemas que podemos encontrar também se tornaram mais claros e isso levou a novas ações. Antes de nós estava a escolha da tecnologia.

Do lado de fora da janela é o verão de 2017. No twitter e no meio, as disputas não desaparecem, o que é ainda melhor, valorizar ou reagir. Nosso escritório não passou por essa tendência. Os desenvolvedores também se dividiram em dois campos, cada um com seus próprios argumentos. Antes disso, cada um de nós já trabalhou com as duas tecnologias.
Alguém se aproximou do jsx, alguém prefere o html ou pug mais familiar, alguém acredita que a imutabilidade ajuda a monitorar e gerenciar melhor o estado do aplicativo, para alguns isso parece uma complicação excessiva. Por outro lado, cada estrutura nos dá a oportunidade de criar componentes de arquivo único e, para ambos, já existem bibliotecas bastante estáveis ​​com um conjunto de todas as funções necessárias para nós (ssr, gerenciamento de estado global, roteamento, gerenciamento de metadados). Para reagir, é nextjs, e para vue, é nuxtjs. Nuxt no momento da seleção ainda estava na versão beta, mas bastante estável. Porque o processo de desenvolvimento foi construído de tal maneira que inicialmente tenhamos um layout e, em seguida, construamos a parte de back-end e transfira o layout das páginas para o front-end, a escolha da estrutura foi bastante simples. Escolhemos vue e nuxtjs, porque foi decidido criar o site e lançar a API em paralelo. Com essa abordagem, é conveniente compor imediatamente componentes e adicionar lógica a eles. Nossos designers de layout adotaram uma abordagem mais próxima para criar seu html usual.

Um pouco sobre back-end


Em termos de soluções de servidor e, em geral, a escolha de tecnologias para criar o back-end, seguimos o caminho mais familiar. O idioma foi escolhido php, para o qual usamos o framework laravel. Tudo gira em nginx. Como uma solução de banco de dados, temos o mysql.

Início do desenvolvimento, pacotes usados ​​e problemas


O Nuxt fornece pacotes completamente satisfatórios para gerenciarmos o estado do aplicativo (vuex) e o roteamento (vue-router). Portanto, começar a montar o projeto e fixar a lógica nos componentes pode começar imediatamente e, conforme necessário, procurar os pacotes de que precisamos. Antes de tudo, é claro, eu precisava de uma solução para se comunicar com a parte de back-end. Para fazer isso, o axios foi escolhido, o padrão já para todos, e o invólucro do módulo nuxt-axios sobre ele. Também ajudamos imediatamente o projeto a não se perder no ambiente e executar em cada ambiente com a configuração desejada - selecione dotenv e o invólucro do módulo nuxt-dotenv. Para iniciar o desenvolvimento, basta e o processo de layout foi iniciado.

A primeira pausa ocorreu quando foi necessário adicionar um controle deslizante de imagem ao layout. "Onde está meu slider-slider, eu quero jquery" foi ouvido do lado do layout da sala. Uma rápida revisão das soluções prontas revelou vários controles deslizantes adequados para nós. Mas quase todo mundo arrastou uma dependência na forma de jquery, que eu não queria adicionar ao pacote finalizado, aumentando assim seu tamanho. Alguns pacotes não suportavam a renderização do servidor, o que também era importante para nós. Como resultado, a escolha recaiu sobre o impressionante swiper, que atendeu totalmente às nossas necessidades e até um pouco mais. Depois que o controle deslizante foi parafusado, nossos designers de layout permaneceram perdidos por um longo tempo. “Isso é tudo, eu tenho que fazer mais alguma coisa? Basta especificar uma lista de imagens e funciona?

Em seguida, veio a escolha do componente para selecionar as datas. Houve mais sorte rapidamente foi encontrado um invólucro para o nosso amado flatpickr. Tudo o que restou foi modelar um pouco.

Em vários lugares do site, há um mapa. Mas porque não precisávamos de detalhes perfeitos e elaboração do mapa, não havia escolha entre os serviços. No entanto, no momento do desenvolvimento, e mesmo agora, não existem soluções que cubram idealmente todas as nossas necessidades. Com base em todos os prós e contras, o Google Maps e o wrapper vue2-google-maps foram escolhidos. O pacote é grande o suficiente e gera muitos itens desnecessários para nós, mas resolve bem seus problemas.

Em alguns formulários, temos campos para inserir o telefone. O usuário precisa ajudar a entrar no telefone, pois há muitas opções para o formato e, em seguida, trabalhar no futuro com dados inseridos em um único formato é mais fácil. Portanto, você precisa de uma máscara. Eu queria usar a máscara de texto já familiar, e aqui tivemos sorte, eles já tinham uma solução para vue - vue-text-mask.

Esses pacotes cobriam quase todos os nossos requisitos. Tudo o que restava era rastrear cliques fora do componente, o que vue-click-outside ajudou. Implementamos a rolagem rápida da página usando o vue-backtotop. Para trabalhar com datas, use moment.

O tamanho final do pacote e de onde vem 1 megabyte


Deve-se ter em mente que um critério importante na escolha de pacotes era o seu peso.

No meio do projeto, decidimos analisar o projeto final e ver as dimensões da montagem. Os resultados foram, para dizer o mínimo, surpreendentes. O tamanho da gangue app.js tinha pouco mais de 950kb de gzip. A equipe do npm run analytics nos trouxe um gráfico bonito com o tamanho de todos os módulos, a partir do qual percebemos que alguns módulos estão gerando dependências desnecessárias na forma de jquery, lodash, etc. Eles tiveram que recusar esses pacotes e encontrar uma alternativa para eles. Atualmente, o tamanho do pacote inteiro é 480kb gzip.



Observe as dependências e verifique periodicamente o tamanho do seu aplicativo.

Página de carregamento inicial e dados obtidos pela API


O Nuxt fornece uma oportunidade conveniente para preencher a loja com dados no servidor antes de carregar o cliente. Para isso, a ação nuxtServerInit é usada. Parece assim para nós:



Como usamos categorias e algumas outras entidades em vários componentes ao mesmo tempo, era mais conveniente obtê-las imediatamente e colocá-las na loja.

Mas aqui há um problema com o tamanho do json que você obtém. Como o servidor envia todos os dados recebidos para o cliente para a renderização inicial, o tamanho do html pode ser muito grande. Nos deparamos com isso quando, em categorias, começamos a transferir imagens, descrições e outros campos desnecessários para nós em todas as páginas que pertencem a cada categoria. O tamanho do json estava acima de 2mb. Felizmente, isso pode ser facilmente corrigido com a remoção de campos desnecessários dos dados fornecidos pelo servidor.

Vazamentos de memória


Depois de algum tempo, no aplicativo em nosso servidor de teste, começamos a observar um aumento não natural no consumo de memória. O pm2 ocupava até 90% de toda a memória do servidor e o aplicativo falhava periodicamente. Na página do github, o nuxt já apresentava alguns problemas com o mesmo problema.

O problema surgiu quando fizemos várias solicitações no método asyncData de nossas páginas.



Felizmente, os desenvolvedores do nuxt resolveram rapidamente esse problema e atualmente o processo consome cerca de 40 MB de memória.

Problemas interessantes e suas soluções


Artigos de componentes
No painel de controle do site, é possível adicionar artigos e inserir vários blocos no conteúdo do artigo, por exemplo, um bloco com mercadorias.



O HTML que vem do servidor é mais ou menos assim:



$ product-4 indica que o componente Product.vue com o identificador 4. deve estar no lugar desse ponteiro.O Vue nos oferece amplas possibilidades para renderizar o componente usando o método render. Primeiro, procuramos todas as referências a ponteiros para componentes no html que chegaram e obtemos pela API os dados necessários para exibir esse componente. Em seguida, dividimos o html inteiro em uma árvore. A biblioteca do Himalaia nos ajudou com isso. E então coletamos o html de volta substituindo ponteiros por componentes prontos.

... E não havia força suficiente para escrever um artigo) Eles começaram a escrever o artigo no verão de 2017, durante o desenvolvimento do projeto, e já é verão de 2018 no quintal, o projeto foi lançado e o artigo não foi lançado.
Portanto, publicamos o que reunimos, mas ainda temos muitos tópicos e observações interessantes.
Se for interessante - escreva, goste)) Bem, o que mais seria interessante ouvir sobre isso, que você perdeu.

Quero dizer que o projeto trabalha há cerca de 4 meses. Não houve problemas especiais, e a velocidade do site é impressionante e o diferencia de outras lojas.

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


All Articles