
Olá, meu nome é Boris Shabanov , sou o chefe de desenvolvimento do Frontend no departamento de desenvolvimento de tecnologias de publicidade do Rambler Group. Hoje vou falar sobre como surgiram os problemas de roteamento em nosso aplicativo e como resolvemos eles.
Advertising Technologies é um grande departamento do Rambler Group que implementa uma pilha completa de tecnologias de publicidade (SSP, DMP, DSP). Para usuários finais, como anunciantes e agências, criamos uma interface conveniente chamada Summer , na qual eles podem lançar suas campanhas publicitárias, analisar estatísticas e gerenciar tudo.
A interface do verão é um conjunto de telas, formulários conectados por links entre si. Estando em um só lugar, em poucos cliques, o usuário pode encontrar as informações de que precisa.

Após vários anos de operação, os requisitos do projeto ficaram mais sérios e percebemos que precisávamos consertar isso. Como o projeto foi baseado no React desde o início, adotamos o aplicativo React Create como base para a nova versão. E GraphQL - para interação com o servidor, a saber - cliente Apollo . Além disso, o departamento tem muita experiência.
Mas tivemos uma pergunta e o que pode ser usado para rotear nosso aplicativo? Fomos ao Google procurar uma solução com as palavras "reagir" e "roteador" e, de fato, nas 5 primeiras páginas, não encontramos nada além de um roteador de reação . "Bem, ok ..." - pensamos, as pessoas inteligentes recomendam, devemos tomar. Após um curto período de perguntas não se tornou menor. Por exemplo, considere um exemplo simples de uso do react-router:
import React from "react"; import { BrowserRouter as Router, Route, Link } from "react-router-dom"; const ParamsExample = () => ( <Router> <div> <h2>Accounts</h2> <ul> <li> <Link to="/netflix">Netflix</Link> </li> <li> <Link to="/zillow-group">Zillow Group</Link> </li> <li> <Link to="/yahoo">Yahoo</Link> </li> <li> <Link to="/modus-create">Modus Create</Link> </li> </ul> <Route path="/:id" component={Child} /> <Route path="/order/:direction" component={ComponentWithRegex} /> </div> </Router> );
Surgem perguntas:
- Que tal um URL com muitos parâmetros?
- O que devo fazer se o gerente de produtos chegar e solicitar que eu mude o URL da página para um mais "amigável"? O "commit do tapete" em todo o projeto realmente não quer fazer.
Durante o processo de desenvolvimento, começamos a pensar e procurar soluções, mas ao mesmo tempo ainda vivíamos no roteador React .
No próximo sprint, levamos a seção "Ajuda" para o trabalho. Não é uma página complicada, e em poucas horas nós a criamos.
Mas o ponto principal é que "Ajuda" é uma seção para a qual todas as outras páginas possuem links, e há muitos links para ela. E o link para cada resposta é gerado dinamicamente. Para nós, esse foi outro motivo para pensar em mudar o roteador.
Após extensas pesquisas na Internet, encontramos uma solução aceitável - Router5 .

Router5 é uma biblioteca que não tem nada a ver com o React, você pode usá-lo com o Angular, com o jQuery, com qualquer coisa. Vale a pena dizer imediatamente que o Router5 não é uma continuação do React-router @ 4, são duas coisas diferentes, desenvolvidas por pessoas diferentes, e não estão conectadas de forma alguma.
Assim, ao escolher uma biblioteca, começamos a ver como ela é popular e se faz sentido usá-la. Se você comparar pelo número de estrelas no github, a vantagem é para o react-router.

Mas decidimos arriscar. Vimos como o projeto vive, se alguém está envolvido em seu desenvolvimento, vimos que as pessoas estão trazendo coisas novas para ele, e o projeto está muito vivo.

A partir da documentação, você pode descobrir que ele tem várias integrações com diferentes estruturas e bibliotecas. Em particular, a documentação descreve a integração com o react e o redux, mas se você pesquisar bem, poderá encontrar exemplos com o mobX lá.

Como são construídas as interfaces e como os roteadores são construídos no Router5?
A história é a mesma aqui no roteador React: cada rota é um contêiner para seus filhos.
Suponha que você tenha um site que consiste em uma página de destino (a página inicial será essa) e existe um determinado painel de administração que consiste em duas seções - uma lista de usuários e uma lista de grupos desses usuários. Podemos configurar tudo isso de maneira que nossa seção Página inicial pareça uma página de destino. Além disso, a seção admin terá um wrapper para todas as páginas e elementos filhos, ou seja, consistirá em um rodapé e um cabeçalho, por exemplo. Todas as subpáginas que já estão na área administrativa se transformarão nesses rodapés e cabeçalhos.

Para esse site, a configuração do Router5 será a seguinte:
import createRouter from 'router5'; import browserPlugin from 'router5/plugins/browser'; const routes = [ { name : 'home', }, { name : 'admin', children : [ { name : 'roles', }, { name : 'users', }, ] }, ]; const options = { defaultRoute: 'home',
No exemplo, temos uma opção simples, mas na verdade você pode aprender muito mais com a documentação e escolher um formato mais conveniente para si mesmo.
Como eu disse anteriormente, usamos o React em nossos projetos na divisão, por isso continuarei falando e mostrando exemplos mais a respeito do React. O exemplo de código abaixo mostra como criar um projeto usando o roteador @ 5.
Ainda mais interessante. O que gostamos e muito elegantemente encaixamos no projeto é como as transições são feitas. Digamos que tenhamos um site com a estrutura descrita acima. E nosso usuário deseja ir da página de destino para a seção "Lista de usuários". O que o router5 fará neste caso? Primeiro, desativa a seção inicial, causando os eventos correspondentes. Os eventos podem ser processados na própria rota e no middleware, onde todas essas transições podem ser processadas. Em seguida, são gerados eventos de ativação para as rotas admin e admin.users.

Em nosso aplicativo, todo o middleware é coletado em um único local. Estes são middlewares, responsáveis por carregar os componentes (tentamos "cortar" o aplicativo em pedaços e carregar as peças que o usuário precisa agora), localização, recebimento de dados do servidor, verificação de direitos de acesso e coleta de análises de transição. Como resultado, os desenvolvedores nem pensam em como receber dados, verificar permissões e o que exibir na tela. Eles fazem a próxima seção e o Roteador5 resolve todos os problemas.
Outro problema que queríamos resolver de uma vez por todas é carregar o aplicativo, dividido em partes diferentes. Na minha opinião, o download de um aplicativo com o React-router é semelhante às aventuras do Hedgehog no nevoeiro. Carregando algumas partes e dados em cada estágio, seu aplicativo não está imune a erros no recebimento de dados do servidor. E, nesse caso, seus projetistas devem apresentar o status das telas para cada situação de emergência. Parece que, nesse local, a probabilidade de erro de um desenvolvedor é alta (ele pode simplesmente se esquecer) e esses riscos devem ser minimizados.
No Roteador5, isso foi decidido pelo fato de que cada transição é realizada de maneira transacional, e a alteração da parte visual não ocorrerá até que todo o middleware tenha sido elaborado, e o roteador está convencido de que nosso aplicativo pode extrair o que queremos dele. Essa abordagem tem suas desvantagens e vantagens, mas, no nosso caso, havia mais vantagens. O problema com o indicador de carregamento é resolvido imediatamente. Nosso aplicativo usa um indicador de download, que é controlado pelo roteador.
Infelizmente, trabalhar com middleware há cerca de 3 ou 4 meses atrás não foi totalmente divulgado na documentação. Mas, investigando os problemas, encontramos um ótimo exemplo que mostra como implantar e criar um aplicativo usando React, Redux e Router5.
Cada um dos URLs de nosso aplicativo armazena um determinado conjunto de dados que precisamos exibir (identificadores, opções adicionais de filtragem de dados etc.). A serialização e desserialização desses parâmetros da URL para o roteador5 e vice-versa não parece sobrenatural, mas é.
export default { name: 'help', path: '/help*slugs', loadComponent: () => import('./index'), encodeParams: ({ slugs }) => slugs.join('/'), decodeParams: ({ slugs }) => slugs.split('/'),, defaultParams: { slugs: [], }, };
Para o nosso projeto, esse foi um parâmetro importante para a escolha de um roteador, pois nosso aplicativo possui muitos filtros e pop-ups. E deve aparecer no URL que indica que o usuário agora vê na tela. Se o usuário quiser mostrar algo ao colega, ele simplesmente atrapalha o URL na barra de endereços do navegador.
A seguir, exemplos básicos:
const router = router5([ { name: 'admin', path: '/admin' }, { name: 'admin.users', path: '~//users?param1' }, { name: 'admin.user', path: '^/user/:id' }, { name: 'help', path: '^/help/*splat' } ]); console.log(router.buildPath('admin'));
No componente React, a formação do link ocorre da seguinte maneira:
import React from 'react' import { Link } from 'react-router5' function Menu(props) { return ( <nav> <Link routeName="home">Home</Link> <Link routeName="about">About</Link> <Link routeName="user" routeParams={{ id: 100 }}>User #100</Link> </nav> ) } export default Menu
Ao criar sites simples que consistem em 3-4 páginas com um número mínimo de transições, não uso o Roteador5, mas o React-router. Mas em projetos com muitas páginas e links, minha escolha será pelo roteador5.
Você também pode assistir a um vídeo da minha performance no RamblerFront & # 5 aqui:
PS Na primeira quinzena de outubro de 2018, planejamos realizar o próximo RamblerFront & # 6. Siga o anúncio aqui em habr.com.