
No último artigo, falamos sobre como surgiu a idéia de escrever nosso próprio painel de controle de hospedagem e sobre a estrutura geral do painel finalizado.
Hoje, nosso desenvolvedor de front-end Artysh dirá como ele escreveu o front-end deste painel: qual estrutura foi escolhida, qual antipadrão é considerado uma boa forma e como se defender contra backdoors se você usar bibliotecas prontas.
Escolha da estrutura: por que você estava procurando por uma nova
O painel anterior foi implementado em sua própria estrutura, escrita em jQuery. Sentamos no VMManager, exigindo muitas melhorias: em termos de interface e funcionalidade, era difícil manter esse código. A adição de novas funcionalidades ao painel pela frente levou muito tempo. É claro que, se desejar, você pode implementar uma boa estrutura em jQuery (eu ainda amo jQuery) ou até mesmo uma aparência de CMS, mas essa não era a melhor opção: começar com uma documentação insuficiente em uma estrutura auto-escrita e terminar com a arquitetura não totalmente correta do próprio aplicativo.
O painel antigo foi implementado como um aplicativo de página única e foi aí que suas boas qualidades terminaram. Depois de resolver outro quebra-cabeça para adicionar um botão à lista, percebi que precisava de uma alternativa. A escolha recaiu sobre Vue.
Porquê SPA?
O aplicativo de página única é a escolha ideal para um painel de controle. O painel de controle em termos de renderização é uma coisa bastante simples, esse trabalho pode ser facilmente confiado ao navegador do usuário. Além disso, a otimização de SEO não é importante para o painel, por isso, temos um site principal. Bem, os usuários do painel percebem o tempo necessário para o carregamento inicial de todos os scripts necessários devido às especificidades desses próprios usuários. Novamente, o back-end que obtivemos foi um serviço RestAPI clássico - para fornecer uma API aberta aos nossos clientes no futuro.
O aplicativo SPA acabou sendo tão leve que funciona bem com o navegador de telefones e tablets - acabamos de fazer um layout adaptável e não precisamos criar um aplicativo separado.
Por que Vue?
Há 3 anos, o Vue era uma estrutura relativamente jovem, mas mesmo assim eles conversaram e escreveram muito sobre isso, e quando o lançamento da versão 2.0 foi lançado, decidimos apostar nele - e estávamos certos. No início, eles planejavam substituir gradualmente alguns componentes escritos em jQuery e Vue, facilitando a execução. Porém, depois que os componentes bastante volumosos foram reescritos, eles decidiram que era melhor reescrever o aplicativo inteiro no Vue.
Este seria um passo arriscado e decidimos adotá-lo por 4 razões:
- Vue é uma estrutura declarativa simples, que até os codificadores podem entender. Se for o caso, é fácil encontrar um desenvolvedor para ele ou apenas ensinar a um amigo. Isso significa que não teremos problemas em encontrar um novo desenvolvedor e entrar no projeto se um bonde me cruzar (louvor aos deuses, eles não estão na minha cidade).
- O Vue é objetivamente bom para escrever aplicativos SPA.
- Eu tive a experiência de desenvolver o React diante dos meus olhos e sugeri que a popularidade do Vue também aumentasse. Agora, a estrutura está incluída no TOP-3 das estruturas JS populares (isso é fácil de verificar com uma consulta de pesquisa), perdendo apenas para React e Angular. Ele tem um bom apoio, um ecossistema desenvolvido e uma grande comunidade.
- Velocidade de desenvolvimento. Pessoalmente, imediatamente comecei a perceber o Vue como um tipo de construtor e o desenvolvimento ocorre rapidamente: se eu precisar, por exemplo, de um selecionador de datas, provavelmente no Vue já existe, é livre para usar e testar pela comunidade. Acabei de instalar o componente no projeto, escrevo uma tag e tudo funciona. De fato, nosso painel consiste em 70 a 80% das bibliotecas concluídas. Quero dizer o uso do componente, não o tamanho da base de código, que pode ser verificada com um comando como: npx intrinsic / loc
Ao implementar um projeto, você sempre leva em consideração suas perspectivas, principalmente as perspectivas de desenvolvimento. E o fato de os ecossistemas Vue já possuírem ferramentas como Weex, Quasar Framework ou Nuxt para mim expandem significativamente os horizontes do desenvolvimento de nossos painéis.
No Habré, há um
artigo maravilhoso sobre o Vue , criado por seu criador, e vou falar sobre alguns recursos do nosso aplicativo.
Vuex Sync com serviço RestAPI
Parte dos dados de armazenamento global da Vuex em nosso aplicativo é sincronizada com o RestAPI por meio de solicitações comuns nos endereços correspondentes. Por que fizemos isso? Bem, pelo menos para que as principais configurações do usuário não estejam vinculadas a um navegador específico de um dispositivo específico. Você pode entrar em nosso painel no computador de sua esposa ou em um clube de jogos e, ao mesmo tempo, entrar no mesmo ambiente familiar que você tinha em seu próprio carro.
Além disso, quando a sincronização era apenas com o localStorage, alguns navegadores perdiam o conteúdo do localStorage durante as atualizações - ele foi completamente excluído. Sim, e recentemente houve uma tendência a restringir a política de armazenamento de dados do usuário em cookies, por exemplo, uma função no
WebKit Intelligent Tracking Prevention - por uma hora eles chegarão ao localStorage.
Barramento de evento
Sim, usamos o barramento de evento global. Como em qualquer outro aplicativo grande com muitos componentes, mais cedo ou mais tarde é necessário estabelecer a interação entre componentes não relacionados. Mesmo através do armazenamento global. É claro que, se houver um relacionamento pai-filho, a interação deles será organizada de maneira padrão pelas propriedades dos props em uma direção e o método $ emit na outra, ou pelo armazenamento,
conforme descrito nas recomendações da Vue .
Mas a documentação também
descreve a possibilidade de usar o barramento de eventos global . Temos vários formulários no projeto com diferentes conjuntos de campos e, em alguns casos (existem alguns deles, mas todos são fundamentais), você precisa de alguma forma reagir de uma maneira especial para alterar o valor do campo. Não faz sentido armazenar os valores de todos os campos de cada formulário no armazenamento global:
- Em primeiro lugar, devido à rara necessidade
- Em segundo lugar, todos os nossos formulários são gerados dinamicamente e o conjunto de campos para qualquer formulário pode mudar drasticamente.
Então eu decidi usar o mecanismo de barramento de eventos. Ao mesmo tempo, nada impede que você use seu emissor de eventos - o principal é usar esse mecanismo com cuidado, apenas para situações excepcionais e limpar tudo com cuidado.
Interação RestAPI com o painel
Para tornar a interface mais responsiva na estrutura jQuery antiga, os comentários do RestAPI para o aplicativo cliente foram emulados por meio de um sistema de timer astuto: ele executou pesquisas RestAPI em um determinado intervalo e redesenhou os nós do DOM que afetavam as alterações.
Essa não era uma solução ideal: em todos os navegadores modernos, os temporizadores congelam quase completamente quando a guia se torna inativa e recebe baixa prioridade. Como resultado, uma solicitação para o serviço RestAPI pode ser adiada e receber dados já irrelevantes.
Para resolver esse problema em um novo painel, decidi usar o pacote do
módulo Nchan para o servidor da web Nginx e os novos recursos das interfaces HTML5 - EventSource e WebWorker.
O módulo Nchan suporta o envio de mensagens através do Websocket, EventSource e Long-Polling. Realizei vários testes e decidi usar o EventSource: as mensagens podem ser apenas texto e as mensagens fluem apenas em uma direção (do servidor). Isso resolveu completamente a tarefa.
Agora a interface EventSource opera em um thread de segundo plano separado do WebWorker, independentemente da atividade da guia. No mesmo encadeamento, uma fila de mensagens primitivas é organizada para que nada seja perdido. A fila é enviada para o thread principal do aplicativo, que, por sua vez, produz os redesenhos necessários da interface quando é conveniente e permite o navegador.
Backdoors: como e por que verifico a segurança dos componentes
Antes de conectar a biblioteca, é obrigatório verificar se há segurança: houve um caso em que um componente introduziu especificamente um backdoor, o que permitiu acessar o site e fazer o download de dados.
Porém, mais frequentemente, as brechas de segurança parecem mais prováveis devido à negligência dos desenvolvedores. Nos mercados de aplicativos, há uma equipe que verifica os componentes quanto à segurança, mas não é muito complicado e é melhor verificar as bibliotecas manualmente.
Eu sempre verifico os pacotes quanto aos ganchos de pré-instalação, instalação e pós-instalação no campo "scripts" do arquivo "package.json". Além disso, uso analisadores de pacotes estáticos, como
aposentar ,
snyk e o comando "audit" do gerenciador de pacotes npm.
Os avisos de segurança vêm em níveis diferentes, geralmente durante a verificação, quando não são críticos. Às vezes, para tratar uma biblioteca, basta atualizar - os próprios desenvolvedores da biblioteca monitoram a segurança.
Se uma biblioteca se comprometeu uma vez, é melhor substituí-la - isso é um sinal de falta de confiabilidade; portanto, com os avisos, escolho procurar outra biblioteca.
Após o pacote ter passado na análise, definitivamente corrigirei sua versão. Se você precisar de uma versão diferente - o pacote passa na análise novamente. Sim, leva tempo, mas vale a pena.
Até agora, os backdoors nunca chegaram à nossa produção.
Muitos muitos comentários
Como eu disse, o Vue foi escolhido por sua simplicidade e declaratividade. Além disso, escrevo muitos comentários, em quase todas as linhas: para que, nesse caso, o novo desenvolvedor possa entrar facilmente no projeto e para que eu próprio volte facilmente aos trechos de código antigos.
Por que eu me apaixonei pelo novo frontend e pelo painel como um todo
Tornou-se mais fácil manter o código
O desenvolvimento levou meio ano. Agora, provavelmente, estou mais envolvido no suporte ao painel, meu código não pressiona e não esfrega.
Os clientes podem obter rapidamente o que solicitaram.

Tornou-se rápido e conveniente adicionar novos recursos que apareciam no back-end: por exemplo, adicionei o pagamento para pessoas jurídicas em 2 dias e as capturas instantâneas em 1 dia.
Estou aberto a perguntas
Neste artigo, revelei alguns dos segredos relacionados ao frontend do nosso painel. Se você tiver alguma dúvida - bem-vindo ao comentar, tentarei responder.
E, é claro, convido você a expressar sugestões para melhorar o painel.

Inscreva-se no nosso desenvolvedor do Instagram
