Membuat dan memelihara komponen umum adalah proses di mana banyak tim harus dilibatkan. Kepala layanan komponen umum Yandex, Vladimir Grinenko
tadatuta menjelaskan bagaimana pengembangan mereka mengungguli tim Lego yang berdedikasi, bagaimana kami membuat repositori mono berdasarkan GitHub menggunakan Lerna, dan mengatur rilis Canary dengan layanan yang diimplementasikan langsung di CI, apa yang dibutuhkan dan apa masih harus.

"Senang menyambut Anda semua." Nama saya Vladimir, saya melakukan hal-hal umum di antarmuka Yandex. Saya ingin berbicara tentang mereka. Mungkin, jika Anda tidak menggunakan layanan kami sangat dalam, Anda mungkin memiliki pertanyaan: apa yang kita semua susunan huruf? Apa yang ada untuk mengeset?


Ada daftar jawaban di hasil pencarian, terkadang ada kolom di sebelah kanan. Anda masing-masing mungkin akan mengatasinya dalam sehari. Jika Anda ingat bahwa ada berbagai peramban dan sebagainya, maka kami menambahkan hari lain untuk memperbaiki bug, dan kemudian semua orang akan mengatasinya.

Seseorang akan ingat bahwa masih ada antarmuka seperti itu. Mempertimbangkan semua hal kecil yang dapat Anda berikan padanya seminggu lagi dan lakukanlah. Dan Dima baru saja memberi tahu kami bahwa ada begitu banyak di antara kita yang membutuhkan sekolah kita sendiri. Dan semua orang ini membuat halaman sepanjang waktu. Setiap hari mereka datang untuk bekerja dan mengeset, bayangkan? Jelas ada sesuatu yang lain.

Bahkan, layanan di Yandex memang lebih banyak. Dan bahkan ada lebih dari pada slide ini. Di balik setiap tautan tersebut terdapat banyak antarmuka yang berbeda dengan variabilitas yang hebat. Mereka untuk perangkat yang berbeda, dalam bahasa yang berbeda. Mereka kadang-kadang bekerja bahkan di mobil dan berbagai hal aneh lainnya.

Yandex hari ini bukan hanya web, tidak hanya barang yang berbeda dengan gudang, pengiriman dan semua itu. Mobil naik kuning. Dan tidak hanya apa yang bisa Anda makan, dan tidak hanya potongan besi. Dan tidak hanya segala macam kecerdasan otomatis. Tetapi semua hal di atas disatukan oleh fakta bahwa untuk setiap antarmuka item diperlukan. Seringkali - sangat kaya. Yandex adalah ratusan layanan besar yang berbeda. Kami terus menciptakan sesuatu yang baru setiap hari. Kami memiliki ribuan karyawan, termasuk ratusan pengembang front-end dan pengembang antarmuka. Orang-orang ini bekerja di kantor yang berbeda, hidup di zona waktu yang berbeda, orang-orang baru terus bekerja.
Pada saat yang sama, kami, sejauh kami memiliki kekuatan yang cukup, mencoba menjadikannya monoton, seragam untuk pengguna.

Ini adalah pencarian dokumen di Internet. Tetapi jika kita beralih ke mengeluarkan gambar, tajuk cocok, terlepas dari kenyataan bahwa ini adalah repositori terpisah, yang bergerak dalam tim yang sepenuhnya terpisah, bahkan mungkin pada teknologi lain. Tampaknya ada yang rumit? Ya, mereka membuat topi dua kali, seperti hal yang sederhana. Setiap tombol di tutupnya juga memiliki dunia batin kaya yang terpisah. Beberapa popup muncul di sini, sesuatu juga dapat didorong ke sana. Semua ini diterjemahkan ke dalam bahasa yang berbeda, berfungsi pada platform yang berbeda. Dan di sini kita beralih dari gambar, misalnya ke video, dan ini lagi layanan baru, tim lain. Repositori lain lagi. Namun topi tetap sama, meski ada perbedaan. Dan semua ini harus dibiarkan seragam.
Apa nilainya, beralih seperti ini di slide, untuk memastikan bahwa tidak ada yang terjadi di piksel? Kami berusaha mencegah hal ini terjadi.

Untuk menunjukkan skala sedikit lebih, saya mengambil screenshot dari repositori, yang hanya menyimpan kode front-end untuk browser baru - hanya output dari dokumen, tanpa gambar dan video. Ada puluhan ribu komitmen dan hampir 400 kontributor. Ini hanya dalam tata letak, hanya satu proyek. Berikut adalah daftar tautan biru yang biasa Anda lihat.
Sergey Berezhnoy, pemimpin saya, sangat menyukai cerita ini, karena sejak kami sangat banyak berkumpul di perusahaan, saya ingin interaksi kami bekerja bersama dalam JavaScript: satu tambah satu lebih dari dua.

Dan kami berusaha mendapatkan semua yang kami bisa dari interaksi. Hal pertama yang muncul dalam pikiran dalam kondisi seperti itu adalah penggunaan kembali. Di sini, misalnya, cuplikan video pada layanan di hasil penelusuran untuk video. Ini adalah semacam gambar dengan tanda tangan dan beberapa elemen berbeda lainnya.

Jika Anda melihat lebih jauh, inilah penerbitan dokumen yang biasa. Tapi di sini juga, ada potongan yang persis sama.

Atau, katakanlah, ada layanan Yandex.Air yang terpisah, yang sedikit kurang lengkap terdiri dari cuplikan serupa.

Atau, katakanlah, cuplikan video di pemberi notifikasi, yang ada di halaman portal yang berbeda.

Atau di sini adalah cuplikan video ketika Anda menambahkannya ke Favorit Anda, dan kemudian menontonnya di Koleksi Anda.

Kedengarannya seperti? Jelas, sepertinya. Jadi apa Jika kami benar-benar membiarkan layanan dengan mudah mengintegrasikan komponen jadi kami ke layanan portal lain, maka jelas layanan ini, karena fakta bahwa pengguna dapat berinteraksi dengan data mereka pada platform yang berbeda, akan mendapatkan lebih banyak pengguna. Ini bagus. Pengguna juga akan mendapat manfaat dari ini. Mereka akan melihat hal yang sama secara merata. Mereka akan berperilaku seperti biasa. Artinya, orang tidak perlu menebak lagi dan lagi apa yang ada dalam pikiran perancang di sini dan bagaimana berinteraksi dengannya.
Dan akhirnya, perusahaan akan mendapatkan penghematan yang jelas dari ini. Selain itu, sepertinya - apa yang ada untuk membuat pratinjau video dan semacam tanda tangan / Bahkan, untuk mendapatkannya begitu saja, Anda perlu melakukan banyak eksperimen yang berbeda, menguji hipotesis yang berbeda, memilih ukuran, warna, indentasi. Tambahkan beberapa elemen, mungkin, lalu hapus, karena mereka tidak terbang. Dan apa yang terjadi, apa yang benar-benar berfungsi, adalah hasil dari proses yang sangat panjang. Dan jika setiap waktu di setiap tempat baru untuk melakukannya lagi, ini adalah upaya yang sangat besar.
Sekarang bayangkan. Katakanlah kita punya sesuatu yang bekerja dengan baik. Di mana-mana, di mana pun mereka menerapkannya, dan kemudian mereka melakukan percobaan baru dan menyadari apa yang bisa ditingkatkan. Dan lagi, kita harus mengulangi seluruh rantai implementasi ini. Mahal

Ok, tampaknya jelas untuk digunakan kembali dengan baik. Tapi sekarang kita harus menyelesaikan sejumlah masalah baru. Anda perlu memahami di mana menyimpan kode baru tersebut. Di satu sisi, tampaknya logis. Di sini kami memiliki cuplikan video, dibuat oleh tim video, mereka memiliki repositori dengan proyek mereka. Mungkin harus diletakkan di sana. Tetapi bagaimana kemudian mendistribusikannya ke repositori lain dari semua orang lain? Dan jika orang lain ingin membawa sesuatu sendiri ke cuplikan ini? Sekali lagi tidak jelas.
Hal ini diperlukan untuk versi itu entah bagaimana. Anda tidak dapat mengubah apa pun, dan, voila, semuanya tiba-tiba bergulir. Sesuatu perlu diuji. Selain itu, kami, misalnya, menguji ini pada layanan video itu sendiri. Tetapi bagaimana jika, ketika diintegrasikan ke dalam layanan lain, ada yang rusak? Sekali lagi tidak jelas.
Pada akhirnya, perlu entah bagaimana memastikan pengiriman cukup cepat ke layanan yang berbeda, karena akan aneh jika kita memiliki suatu tempat versi sebelumnya, suatu tempat yang baru. Pengguna tampaknya mengklik pada hal yang sama, dan ada perilaku yang berbeda. Dan kita perlu menyediakan kesempatan bagi pengembang tim yang berbeda untuk melakukan perubahan pada kode umum tersebut. Kita perlu mengajar mereka bagaimana cara menggunakannya. Kami memiliki jalan panjang untuk membuat antarmuka penggunaan kembali nyaman.

Kami mulai di zaman dahulu, kembali di SVN, dan itu seperti lampu dan nyaman: seorang ayah dengan HTML, sama seperti di Bootstrap. Anda menyalinnya ke diri Anda sendiri. Di sebelah ayah dengan gaya, semacam JS di sana, yang kemudian tahu cara hanya menunjukkan / menyembunyikan sesuatu. Dan itu saja.

Entah bagaimana daftar komponennya terlihat seperti ini. B-domeg, yang bertanggung jawab atas otorisasi, disorot di sini. Mungkin Anda masih ingat, di Yandex, memang ada formulir untuk masuk dan kata sandi, dengan atap. Kami menyebut "rumah", meskipun mengisyaratkan amplop surat, karena mereka biasanya memasukkan surat.
Lalu kami datang dengan metodologi keseluruhan untuk dapat mendukung antarmuka umum.

Perpustakaan itu sendiri di dalam perusahaan telah memperoleh situs web sendiri dengan pencarian dan taksonomi apa pun.

Repositori sekarang terlihat seperti ini. Soalnya, juga hampir 10 ribu komitmen dan lebih dari 100 kontributor.

Tapi ini adalah folder dari b-house di reinkarnasi baru. Sekarang dia terlihat seperti ini. Sudah ada lebih banyak folder Anda sendiri di dalam dari setengah layar.

Dan situsnya terlihat hari ini.

Akibatnya, perpustakaan bersama digunakan di lebih dari 360 repositori di dalam Yandex. Dan ada implementasi yang berbeda, siklus rilis yang di-debug, dll. Tampaknya, di sini, kami memiliki perpustakaan umum, sekarang mari kita gunakan di mana-mana, dan semuanya hebat. Masalah memperkenalkan hal-hal umum di mana saja diselesaikan. Tidak juga.

Mencoba menyelesaikan masalah penggunaan kembali pada tahap ketika Anda sudah memiliki kode siap pakai sudah terlambat. Ini berarti bahwa sejak perancang menggambar tata letak layanan, mendistribusikannya ke layanan, dan, khususnya, kepada tim yang berurusan dengan komponen umum, beberapa waktu telah berlalu. Kemungkinan besar, saat ini akan berubah sehingga pada setiap layanan terpisah, atau setidaknya pada beberapa dari mereka, elemen antarmuka yang sama ini juga dibuat. Entah bagaimana mereka mengarang dengan cara mereka sendiri.
Dan bahkan jika solusi umum muncul kemudian di perpustakaan bersama, itu masih akan berubah sehingga Anda sekarang harus mengimplementasikan kembali semua yang Anda berhasil selesaikan pada setiap layanan. Dan ini lagi-lagi masalah. Sangat sulit untuk dibenarkan. Ini timnya. Dia memiliki tujuan sendiri, semuanya sudah bekerja dengan baik. Dan kami mengatakan hal-hal seperti itu - lihat, akhirnya kami memiliki hal kecil yang umum, ambillah. Tetapi tim seperti itu - kami sudah memiliki cukup banyak pekerjaan. Mengapa kita membutuhkannya? Apalagi tiba-tiba ada sesuatu yang tidak cocok dengan kita di sana? Kami tidak mau.
Masalah besar kedua adalah, pada kenyataannya, penyebaran informasi tentang apa komponen baru yang keren ini. Hanya karena ada begitu banyak pengembang, mereka sibuk dengan tugas sehari-hari mereka. Dan mereka memiliki kesempatan untuk duduk dan mempelajari apa yang terjadi di sana dalam bidang yang sama, tidak peduli apa artinya, sebenarnya, baik.
Dan masalah terbesar adalah bahwa pada dasarnya tidak mungkin untuk menyelesaikan masalah umum untuk semua layanan dengan satu tim khusus. Yaitu, saat kami memiliki tim yang menangani video, dan membuat cuplikannya sendiri dengan video, jelas bahwa kami akan setuju dengan mereka dan melakukan cuplikan ini di semacam perpustakaan terpusat. Tetapi ada ribuan contoh langsung tentang layanan yang berbeda. Dan di sini tentu saja tidak ada tangan yang cukup. Oleh karena itu, satu-satunya solusi adalah bahwa setiap orang harus berurusan dengan komponen umum setiap saat.

Dan Anda perlu memulai, anehnya, bukan dengan pengembang antarmuka, tetapi dengan desainer. Mereka juga mengerti itu. Kami memiliki beberapa upaya simultan di dalam sehingga proses ini bertemu. Desainer membuat sistem desain. Saya sangat berharap bahwa cepat atau lambat akan mungkin untuk menguranginya menjadi satu sistem tunggal yang memperhitungkan semua kebutuhan.

Sekarang ada beberapa dari mereka. Anehnya, tugas-tugas di sana persis sama: untuk mempercepat proses pengembangan, untuk menyelesaikan masalah konsistensi, bukan untuk menemukan kembali roda dan tidak menduplikasi pekerjaan yang dilakukan.

Dan salah satu cara untuk memecahkan masalah dalam mengkomunikasikan informasi adalah dengan memungkinkan pengembang untuk mengenal tim lain, termasuk yang berhubungan dengan komponen antarmuka umum. Kami menyelesaikannya di sisi ini dengan fakta bahwa kami memiliki bootcamp, yang, ketika pengembang muncul di Yandex, pertama-tama memungkinkan dia untuk pergi ke tim yang berbeda selama delapan minggu, melihat cara kerjanya, dan kemudian membuat pilihan di mana ia akan bekerja . Tetapi selama ini cakrawala-Nya akan berkembang secara signifikan. Dia akan dibimbing di mana itu.
Kami berbicara tentang hal-hal umum. Sekarang mari kita lihat bagaimana semuanya terlihat lebih dekat dengan proses pengembangan. Katakanlah kita memiliki perpustakaan umum yang disebut Lego. Dan kami ingin menerapkan beberapa fitur baru di dalamnya atau membuat semacam revisi. Kami memperbaiki kode dan merilis versi.
Kita perlu menerbitkan versi ini di npm, dan kemudian pergi ke repositori beberapa proyek di mana perpustakaan digunakan dan mengimplementasikan versi ini. Kemungkinan besar, ini akan memperbaiki beberapa nomor di package.json, restart perakitan. Mungkin bahkan meregenerasi kunci-paket, membuat permintaan tarik, melihat bagaimana tes lulus. Dan apa yang akan kita lihat?

Kemungkinan besar, kita akan melihat bahwa bug telah terjadi. Karena sangat sulit untuk memprediksi semua cara untuk menggunakan komponen pada layanan yang berbeda. Dan jika itu terjadi, lalu apa jalan keluar kita? Jadi kami menyadari bahwa itu tidak cocok bersama. Kami terus mengulang. Kami kembali ke repositori dengan pustaka bersama, memperbaiki bug, merilis versi baru, mengirimkannya ke npm, menyebarkan, menjalankan tes, dan apa itu? Kemungkinan besar, bug akan terjadi lagi.
Dan ini masih bagus ketika kita mengimplementasikannya dalam satu layanan, dan di sana semuanya langsung rusak. Jauh lebih menyedihkan ketika kami melakukan semua ini, menerapkannya dalam sepuluh layanan yang berbeda. Tidak ada yang pecah di sana. Kami sudah membuat bir smoothie, atau apa pun yang diperlukan. Pada saat ini, versi sedang diperkenalkan di proyek ke-11, atau di ke-25. Dan ada bug. Kami kembali di sepanjang rantai, membuat tambalan dan menerapkannya di semua 20 layanan sebelumnya. Selain itu, tambalan ini dapat meledak di salah satu yang sebelumnya. Baik dan sebagainya. Selamat bersenang-senang.
Tampaknya satu-satunya jalan keluar adalah menulis banyak kode dengan sangat cepat. Kemudian cepat atau lambat, jika kita menjalankan sangat, sangat cepat, kemungkinan besar, kita akan berhasil memiliki waktu untuk memproduksi versi yang belum ada bug. Tapi kemudian fitur baru akan muncul, dan tidak ada yang menyelamatkan kita.
Baiklah Bahkan, skemanya mungkin seperti berikut ini. Otomasi akan membantu kami. Tentang hal ini, secara umum, keseluruhan cerita, sebenarnya. Kami datang dengan gagasan bahwa repositori dengan perpustakaan umum dapat dibangun sesuai dengan skema mono-repositori. Anda mungkin menemukan, sekarang ada banyak proyek seperti itu, terutama yang infrastruktur. Segala macam Babel, dan hal-hal seperti itu, hidup seperti repositori mono ketika ada banyak paket npm yang berbeda di dalamnya. Mereka mungkin entah bagaimana terhubung satu sama lain. Dan mereka dikelola, misalnya, melalui Lerna, sehingga nyaman untuk menerbitkan semua ini, mengingat ketergantungannya.
Tepat sesuai dengan skema ini, dimungkinkan untuk mengatur proyek di mana segala sesuatu yang sama disimpan untuk seluruh perusahaan. Mungkin ada perpustakaan, yang bergerak dalam tim yang terpisah. Dan, termasuk, mungkin ada paket yang dikembangkan masing-masing layanan individu, tetapi ia ingin berbagi dengan yang lain.

Maka sirkuitnya terlihat seperti ini. Awal tidak berbeda. Dengan satu atau lain cara, kita perlu membuat perubahan pada kode umum. Dan kemudian, dengan bantuan otomatisasi, dalam satu gerakan kami ingin menjalankan tes tidak hanya di sebelah kode ini, tetapi segera di semua proyek di mana kode umum ini tertanam. Dan lihat hasil agregat mereka.
Kemudian, bahkan jika bug terjadi di sana, kami masih belum berhasil merilis versi apa pun, belum menerbitkannya dalam waktu berapa pun, kami belum mengimplementasikannya secara khusus dengan tangan kami, kami belum melakukan semua upaya ekstra ini. Kami melihat bug, segera memperbaikinya secara lokal, menjalankan tes umum lagi, dan itu semua dalam produksi.

Seperti apa praktiknya? Berikut adalah permintaan tarik dengan perbaikan. Di sini Anda dapat melihat bahwa otomatisasi meminta pengulas yang diperlukan di sana untuk memeriksa bahwa semuanya baik-baik saja dalam kode. Memang, pengulas datang dan setuju bahwa semuanya baik-baik saja. Dan pada saat ini, pengembang hanya menulis perintah khusus / kenari, tepat di permintaan tarik.
Robot datang dan berkata - oke, saya membuat tugas agar keajaiban berikutnya terjadi. Keajaibannya adalah bahwa versi kenari dengan perubahan ini sekarang telah dirilis dan telah secara otomatis diterapkan di semua repositori di mana komponen ini digunakan. Autotests diluncurkan di sana, seperti dalam repositori ini. Di sini Anda dapat melihat bahwa sejumlah besar cek telah diluncurkan.
Di belakang setiap tes bisa ada seratus tes berbeda. Tetapi penting bahwa selain tes lokal yang kami dapat menulis ke komponen secara terpisah, kami juga meluncurkan tes untuk setiap proyek di mana itu dilaksanakan. Tes integrasi telah diluncurkan di sana: kami memeriksa apakah komponen ini bekerja secara normal di lingkungan di mana ia disusun pada layanan. Ini sudah benar-benar menjamin kita bahwa kita tidak melupakan apa pun, kita tidak merusak apa pun kepada siapa pun. Jika semuanya baik-baik saja di sini, maka kita benar-benar dapat dengan aman merilis versi. Dan jika ada sesuatu yang buruk di sini, kami akan memperbaikinya di sini.
Sepertinya ini akan membantu kita. Jika perusahaan Anda memiliki sesuatu yang serupa, Anda melihat ada bagian-bagian yang berpotensi Anda gunakan kembali, tetapi untuk sekarang Anda harus mengaturnya kembali karena tidak ada otomatisasi, saya sarankan Anda datang ke solusi yang sama.

Apa yang kita dapatkan? Monorepositori umum tempat linters dibangun kembali. Artinya, semua orang menulis kode dengan cara yang sama, ia memiliki semua jenis tes. Setiap tim dapat datang, meletakkan komponen mereka dan mengujinya dengan uji unit JS, menutupinya dengan tangkapan layar, dll. Semuanya sudah di luar kotak. Ulasan kode pintar yang saya sebutkan. Berkat alat internal yang kaya, ini sangat pintar di sini.
Apakah pengembang sedang berlibur sekarang? Memanggilnya menjadi permintaan tarik tidak ada gunanya, sistem akan mempertimbangkan ini. Apakah pengembang sakit? Sistem juga akan mempertimbangkan ini. Jika kedua kondisi tidak terpenuhi dan pengembang tampaknya bebas, ia akan menerima pemberitahuan di salah satu pengirim pesan pilihannya. Dan dia seperti ini: tidak, sekarang saya sibuk dengan sesuatu yang mendesak atau di sebuah pertemuan. Dia bisa datang ke sana dan hanya menulis perintah / sibuk. Sistem akan secara otomatis memahami bahwa Anda perlu menetapkan yang berikutnya dari daftar.
Langkah selanjutnya adalah menerbitkan versi kenari yang sama. Artinya, dengan perubahan kode apa pun, kita perlu merilis paket layanan yang dapat kita periksa pada layanan yang berbeda. Selanjutnya, kita perlu menjalankan tes saat menggunakan ke semua layanan ini. Dan ketika semuanya datang bersamaan - luncurkan rilisnya.
Jika perubahan memengaruhi beberapa statis yang harus dimuat dari CDN, Anda perlu mempublikasikannya secara terpisah. . , , , , . , , , changelog - .
, , , , . , , .
, . . , , : , ? . , . . , .