
Hai, nama saya Boris Shabanov , saya adalah kepala pengembangan Frontend di departemen pengembangan teknologi periklanan dari Grup Rambler. Hari ini saya akan memberitahu Anda bagaimana masalah routing muncul pada aplikasi kami, dan bagaimana kami menyelesaikannya.
Advertising Technologies adalah departemen besar di Rambler Group, yang mengimplementasikan setumpuk penuh teknologi periklanan (SSP, DMP, DSP). Untuk pengguna akhir, yaitu pengiklan dan agensi, kami menciptakan antarmuka yang nyaman yang disebut Musim Panas , di mana mereka dapat meluncurkan kampanye iklan mereka, melihat statistik mereka dan mengelola semuanya.
Antarmuka Musim Panas adalah sekumpulan layar, formulir yang dihubungkan oleh tautan satu sama lain. Berada di satu tempat, dalam beberapa klik pengguna dapat menemukan informasi yang ia butuhkan.

Setelah beberapa tahun beroperasi, persyaratan proyek menjadi lebih serius, dan kami menyadari bahwa kami perlu memperbaikinya. Karena proyek ini pada React dari awal, kami mengambil React Create App sebagai dasar untuk versi baru. Dan GraphQL - untuk interaksi dengan server, yaitu - klien Apollo . Apalagi departemen memiliki banyak keahlian.
Tetapi kami memiliki pertanyaan, dan apa yang dapat digunakan untuk merutekan aplikasi kami? Kami pergi ke Google untuk mencari solusi dengan kata-kata "bereaksi" dan "router", dan, pada kenyataannya, pada 5 halaman pertama kami tidak menemukan apa pun selain React Router . "Baiklah, ok ..." - kami pikir, orang pintar merekomendasikan, kita harus menerima. Setelah beberapa pertanyaan singkat tidak menjadi kurang. Misalnya, ambil contoh sederhana menggunakan 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> );
Muncul pertanyaan:
- Bagaimana dengan URL dengan banyak parameter?
- Apa yang harus saya lakukan jika manajer Produk datang dan meminta saya untuk mengubah URL halaman menjadi yang lebih "ramah"? "Carpet commit" di seluruh proyek tidak benar-benar ingin dilakukan.
Selama proses pengembangan, kami mulai berpikir dan mencari solusi, tetapi pada saat yang sama kami tinggal di React-router .
Pada sprint berikutnya, kami menggunakan bagian "Bantuan" untuk bekerja. Bukan halaman yang rumit, dan dalam beberapa jam kami berhasil.
Tetapi intinya adalah bahwa "Bantuan" adalah bagian yang terhubung ke semua halaman lain, dan ada banyak tautan ke sana. Dan tautan ke setiap jawaban dihasilkan secara dinamis. Bagi kami, ini adalah alasan lain untuk berpikir tentang mengganti router.
Setelah pencarian ekstensif di Internet, kami menemukan solusi yang dapat diterima - Router5 .

Router5 adalah perpustakaan yang tidak ada hubungannya dengan Bereaksi, Anda dapat menggunakannya dengan Angular, dengan jQuery, dengan apa pun. Perlu segera mengatakan bahwa Router5 bukan kelanjutan dari React-router @ 4, mereka adalah dua hal yang berbeda, dikembangkan oleh orang yang berbeda, dan mereka tidak terhubung dengan cara apa pun.
Karena itu, ketika memilih perpustakaan, kami mulai melihat seberapa populernya dan apakah masuk akal untuk menggunakannya sama sekali. Jika Anda membandingkan dengan jumlah bintang di github, maka keuntungannya adalah menuju router reaksi.

Tapi kami memutuskan untuk mengambil risiko. Kami melihat bagaimana proyek itu hidup, apakah seseorang terlibat dalam pengembangannya, melihat bahwa orang membawa hal-hal baru kepadanya, dan proyek itu sangat hidup.

Dari dokumentasi Anda dapat mengetahui bahwa ia memiliki banyak integrasi dengan kerangka kerja dan perpustakaan yang berbeda. Secara khusus, dokumentasi menjelaskan integrasi dengan react dan redux, tetapi jika Anda mencari dengan baik, Anda dapat menemukan contoh dengan mobX di sana.

Bagaimana antarmuka dibangun, dan bagaimana router dibangun di Router5?
Ceritanya sama di sini seperti di React-router: setiap rute adalah wadah untuk anak-anaknya.
Misalkan Anda memiliki situs yang terdiri dari halaman arahan (kami akan membawanya pulang), dan ada panel admin tertentu yang terdiri dari dua bagian - daftar pengguna dan daftar grup pengguna ini. Kami selanjutnya dapat mengonfigurasi semua ini sedemikian rupa sehingga bagian Beranda kami akan terlihat seperti halaman arahan. Lebih lanjut, bagian admin akan memiliki pembungkus untuk semua halaman dan elemen anak-anak, yaitu akan terdiri dari footer dan header, misalnya. Semua subhalaman yang sudah ada di area admin akan berubah menjadi footer dan header ini.

Untuk situs seperti itu, konfigurasi Router5 adalah sebagai berikut:
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',
Dalam contoh ini, kami memiliki opsi sederhana, tetapi sebenarnya Anda dapat belajar lebih banyak dari dokumentasi dan memilih format yang lebih nyaman untuk Anda sendiri.
Seperti yang saya katakan sebelumnya, kami menggunakan Bereaksi pada proyek-proyek kami di divisi, jadi saya akan terus berbicara dan menunjukkan lebih banyak contoh ke arah Bereaksi. Contoh kode di bawah ini menunjukkan cara meningkatkan proyek menggunakan Router @ 5.
Lebih jauh lebih menarik. Hal yang kami sukai dan sangat elegan masuk ke dalam proyek adalah bagaimana transisi dibuat. Katakanlah kita memiliki situs dengan struktur yang dijelaskan di atas. Dan pengguna kami ingin pergi dari halaman arahan ke bagian "Daftar Pengguna". Apa yang akan dilakukan router5 dalam kasus ini? Pertama-tama, ini menonaktifkan bagian beranda, menyebabkan peristiwa yang sesuai. Acara dapat diproses baik di rute itu sendiri maupun di middleware, di mana semua transisi ini dapat diproses. Selanjutnya, acara aktivasi untuk admin dan admin.user rute dihasilkan.

Dalam aplikasi kami, semua middleware dikumpulkan di satu tempat. Ini adalah middleware, yang bertanggung jawab untuk memuat komponen (kami mencoba untuk "memotong" aplikasi menjadi beberapa bagian dan memuat bagian yang dibutuhkan pengguna sekarang), pelokalan, memperoleh data dari server, memeriksa hak akses dan mengumpulkan analitik transisi. Akibatnya, pengembang bahkan tidak memikirkan cara menerima data, memeriksa izin, dan apa yang akan ditampilkan di layar. Mereka membuat bagian selanjutnya, dan Router5 menyelesaikan semua masalah.
Masalah lain yang ingin kami pecahkan sekali dan untuk semua adalah memuat aplikasi, dipecah menjadi beberapa bagian. Menurut pendapat saya, mengunduh aplikasi dengan React-router mirip dengan petualangan Hedgehog di dalam kabut. Memuat beberapa bagian dan data pada setiap tahap, aplikasi Anda tidak kebal terhadap kesalahan dalam menerima data dari server. Dan dalam hal ini, desainer Anda harus memunculkan status layar untuk setiap situasi darurat. Tampaknya di tempat ini probabilitas kesalahan pengembang tinggi (ia mungkin saja melupakannya), dan risiko ini harus diminimalkan.
Di Router5, ini diputuskan oleh fakta bahwa setiap transisi dilakukan secara transaksi, dan perubahan bagian visual tidak akan terjadi sampai semua middleware diselesaikan, dan router yakin bahwa aplikasi kita dapat mengambil apa yang kita inginkan darinya. Pendekatan ini memiliki minus dan plus, tetapi dalam kasus kami ada lebih banyak plus. Masalah dengan indikator pemuatan segera diselesaikan. Aplikasi kami menggunakan satu indikator unduhan, yang dikendalikan oleh router.
Sayangnya, bekerja dengan middleware sekitar 3 atau 4 bulan lalu tidak sepenuhnya diungkapkan dalam dokumentasi. Namun dengan mempelajari berbagai masalah, kami menemukan contoh yang bagus yang menunjukkan cara menggunakan dan membuat aplikasi menggunakan React, Redux, dan Router5.
Setiap URL aplikasi kami menyimpan satu set data tertentu yang kami perlukan untuk menampilkan data (pengidentifikasi, opsi pemfilteran data tambahan, dll.). Serialisasi dan deserialisasi parameter ini dari URL ke router5 dan sebaliknya tidak terlihat supernatural, tetapi itu.
export default { name: 'help', path: '/help*slugs', loadComponent: () => import('./index'), encodeParams: ({ slugs }) => slugs.join('/'), decodeParams: ({ slugs }) => slugs.split('/'),, defaultParams: { slugs: [], }, };
Untuk proyek kami, ini adalah parameter penting untuk memilih router, karena aplikasi kami memiliki banyak filter dan pop-up. Dan itu akan ditampilkan dalam URL yang menyatakan bahwa pengguna sekarang melihat di layar. Jika pengguna ingin menunjukkan sesuatu kepada rekannya, maka ia cukup meraba-raba URL dari bilah alamat browsernya.
Berikut ini adalah contoh dasar:
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'));
Dalam komponen Bereaksi, pembentukan tautan terjadi sebagai berikut:
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
Saat membuat situs sederhana yang terdiri dari 3-4 halaman dengan jumlah transisi minimum, saya tidak menggunakan Router5, tetapi saya menggunakan React-router. Tetapi dalam proyek dengan banyak halaman dan tautan, pilihan saya akan menuju Router5.
Anda juga dapat menonton video kinerja saya di RamblerFront & # 5 di sini:
PS Pada paruh pertama Oktober 2018, kami berencana untuk mengadakan RamblerFront berikutnya & # 6. Ikuti pengumuman di sini di habr.com.