Bagaimana kami menggergaji monolit. Bagian 2, Manajer Bingkai

Hai, nama saya Stas, saya bekerja di tim Tinkoff Business. Di artikel terakhir, kolega saya Vanya memberi tahu bagaimana arsitektur aplikasi kita disusun . Beberapa kali Vanya menyebutkan Frame Manager tertentu, yang berfungsi sebagai orkestrator aplikasi, dan sekarang saya akan memberi tahu Anda lebih detail.



gambar



Apa itu Bisnis Tinkoff



Tinkoff Business menawarkan solusi untuk usaha kecil dan menengah: proyek gaji, kas dan layanan penyelesaian, perancang dokumen dan sekitar 20 produk lainnya.

Semua ini diimplementasikan dalam aplikasi. Aplikasi ini dikembangkan oleh tim terpisah dan memiliki siklus rilisnya sendiri. Selain itu, semua aplikasi ini bekerja dengan satu otorisasi, berisi bagian umum dari logika bisnis, dipindahkan ke pustaka terpisah, dan menggunakan komponen UI umum.



Mari kita kembali ke 2 tahun yang lalu



Aplikasi Tinkoff Business yang khas terlihat seperti ini:



gambar



Di bagian atas adalah header dengan navigasi melalui aplikasi, dan di sebelah kanan adalah sidebar dengan navigasi produk.

Saat itu, ide microfront belum begitu populer, tapi kami sudah bergerak ke arah ini: sidebar adalah aplikasi Angular yang terpisah. Aplikasi utama memuat sidebar ke dalam iframe, yang memungkinkan aplikasi untuk dirilis secara independen.



Pendekatan ini memiliki kekurangan: saat beralih antar produk, Anda harus menunggu pemuatan halaman penuh dengan dua aplikasi Angular. Dan karena sebagian besar aplikasi menggunakan permintaan API backend yang sama, pengguna harus menunggu hingga aplikasi tersebut dijalankan ulang.



Ide Frame Manager



Kami hidup dengan arsitektur seperti itu sampai tugas global untuk semua aplikasi muncul - desain ulang. Kemudian ide muncul: mengapa tidak melakukan semacam inversi kontrol dan bukannya aplikasi memuat sidebar di dalamnya, sidebar akan memuat aplikasi itu sendiri?



Ini memungkinkan untuk mempertahankan keunggulan arsitektur saat ini dan menyingkirkan masalah di atas (dan menghadirkan yang baru, haha).



Prototipe awal



Awalnya, kami membuat prototipe dengan fungsionalitas minimum yang diperlukan untuk memuat aplikasi lain. Sebuah domain terpisah dibuat di bangku tes. Rute di nginx untuk statika aplikasi telah berubah: sebelumnya , statika aplikasi terkait dimuat di sepanjang jalur / sme , / akun , / gaji , dll. Sekarang statika Frame Manager dikirim di semua jalur, dan postfix / static ditambahkan ke rute statis aplikasi itu sendiri .



Untuk membuatnya lebih jelas, mari kita lihat contoh: Anda perlu memuat aplikasi yang terletak di / some-app path dengan some-route . Mengesampingkan detailnya, mari kita lihat proses apa yang terjadi saat memuat / some-app / some-route / :

  1. Nginx mengirimkan statika Frame Manager di sepanjang jalur ini.
  2. Frame Manager sedang dimuat. Berdasarkan rutenya, ia memahami memuat beberapa aplikasi .
  3. Iframe dibuat dengan src = '/ some-app / static /' di mana aplikasi utama dimuat.


Pada saat yang sama, peningkatan yang signifikan diperlukan dalam aplikasi itu sendiri. Oleh karena itu, kami mencabang master cabang aplikasi dan menambahkan perubahan yang diperlukan di sana, setelah itu kami mengangkat masing-masing contoh aplikasi itu sendiri dengan perubahan yang dibuat.



Masalah pertama



Jadi kami mentransfer 4 aplikasi ke Frame Manager dan memastikan bahwa solusinya berfungsi. Semua aplikasi lain harus diterjemahkan. Dan di sini kami mengalami masalah: ternyata terlalu mahal untuk mempertahankan versi reguler dan versi untuk bekerja dengan Frame Manager secara bersamaan.



Kami harus terus memperbarui versi baru aplikasi untuk setiap perubahan ke master versi lama, menyelesaikan konflik yang muncul, fungsionalitas yang ada sering rusak, biaya pengujian regresi hampir dua kali lipat - semua ini memakan waktu terlalu lama. Jelas bahwa solusi baru dibutuhkan.



Perbaikan



Jika satu versi aplikasi dapat bekerja dengan sidebar dan Frame Manager, itu akan menyelamatkan kita dari banyak masalah. Mari kita lihat apa yang bisa dilakukan.



Pertama-tama, Anda perlu menentukan apakah suatu aplikasi sedang berjalan di Frame Manager. Ini cukup sederhana: Anda perlu membandingkan referensi window.top dan window.self. Jika mereka tidak sama, maka kita berada dalam bingkai, yaitu di Manajer Bingkai! Namun, jika ada aplikasi yang terbuka di iframe secara default, Anda perlu menambahkan logika tambahan. Jadi, kami memiliki aplikasi widget yang awalnya dibuka dalam bingkai dan mulai berasumsi bahwa itu selalu ada di Manajer Bingkai, itulah sebabnya ia rusak dalam mode lama.



Sekarang mari kita lihat lebih dekat perubahan apa yang diperlukan dalam aplikasi dan bagaimana Anda dapat mendukung pekerjaan dalam dua mode:

  1. url. iframe, . , - , โ€” . urlโ€™ Frame Manager, . .

  2. . Frame Managerโ€™ . : . . , , , post messages custom events. Frame Manager.

  3. . , Frame Manager. , Angular .

  4. . , , TCS, config.js . Frame Manager .

  5. base href. nginx, base href ( /static/). : , base href , . , , , , base href, .

  6. Otorisasi. Untuk otorisasi di semua aplikasi, skrip terpisah digunakan, yang tertanam di index.html. Di versi baru, skrip ini disematkan di Frame Manager, dan penggunaan ulangnya di aplikasi akan menyebabkan kesalahan. Anda dapat mengubah logika skrip agar diabaikan jika aplikasi dimuat di dalam Frame Manager.



Ini semua adalah solusi yang berfungsi, tetapi tidak cukup fleksibel. Cabang baru telah ditambahkan dengan logika yang juga perlu dipertahankan di tempat berbeda. Secara umum, semuanya tampak seperti struktur yang terlalu rumit dan agak tidak stabil.



Menemukan kembali iframe



Kemudian saya mendapat ide untuk sedikit meretas proses memuat aplikasi index.html. Alih-alih memuat aplikasi ke dalam iframe dengan menentukan atribut src, Anda bisa membuat permintaan xhr untuk index.html, mendapatkan halaman dalam bentuk teks, memprosesnya, dan memuatnya ke dalam iframe. Ini akan memberikan kendali penuh atas aplikasi yang dimuat: ini akan memungkinkan Anda untuk mendefinisikan basis href, menghapus skrip yang tidak perlu, gaya tambalan, mengganti variabel dan banyak lagi!



Ya, penambalan mokey tidak disarankan oleh pengembang dan dianggap praktik yang buruk, tetapi jika tim Angular menggunakannya di pustaka zone.js, bagaimana keadaannya menjadi lebih buruk? Keraguan kinerja dapat muncul: penguraian html terlihat seperti operasi yang mahal. Tetapi, sebagai aturan, halaman awal aplikasi Angular tidak melebihi 50 baris, dan di semua browser (bahkan IE 10!) Ada api yang nyamanDOMParser , yang memungkinkan mendapatkan DOM dari sebuah string.



Mari kita lihat apa yang dilakukan Manajer Bingkai saat memuat aplikasi (Manajer Bingkai itu sendiri sudah dimuat):

  1. Berdasarkan jalur, muat index.html aplikasi.

  2. Mengurai halaman, mengubahnya menjadi DOM, menghapus skrip yang tidak perlu di memori, mengganti href dasar, variabel global dengan konfigurasi dan gaya.

  3. Membuat elemen iframe yang menulis dokumen yang dihasilkan (diubah kembali menjadi string) menggunakan document.write ().
  4. Menempatkan aplikasi sebuah rute yang harus disambungkan. Ini juga memberi makan model yang diperlukan untuk logika bisnis untuk bekerja melalui layanan pertukaran data.



Jadi, dari enam perubahan penting dalam logika, hanya yang pertama (sinkronisasi url) yang perlu diimplementasikan di dalam aplikasi, sisanya diambil alih oleh Frame Manager!



Apa yang didapat



Kami benar-benar mengubah tampilan aplikasi, secara praktis tanpa membuat perubahan apa pun pada kode aplikasi itu sendiri.

Sebelum. Sidebar dilingkari dengan warna merah. Tersemat dalam iframe
sidebar



Setelah. Frame Manager disorot dengan warna merah. Aplikasi dimuat dalam iframe
frame manager



Punya kemampuan untuk mengganti atau menambahkan variabel dan gaya global.

Misalnya, seperti inilah tampilan konfigurasi gaya untuk aplikasi
export const business = {
    'sidebar.b-main__sidebar': {
        display: 'none'
    },
    '.b-main': {
        'margin-left': '260',
        position: 'relative',
        display: 'block',
        width: '1104px',
        'min-height': '100vh',
        margin: '0 auto'
    }
};




Dan - konfigurasi aplikasi itu sendiri
{
        id: 'products',
        name: ' ',
        icon: 'products',
        frameSupported: true,
        applications: [
            {
                id: 'products',
                path: '/products',
                apiPrefix: '/products',
                hasMenuConfig: true,
                dynamicCompanyChange: true,
            }
        ]
    }




Pada saat yang sama, konfigurasi berada di repositori, terpisah dari Frame Manager, yang memungkinkan Anda mengubah beberapa parameter kerja aplikasi tanpa merilisnya.



Kami juga membuat transisi yang mulus antar aplikasi, membuat otorisasi di Frame Manager. Kami telah mencapai itu karena berbagi data antara Frame Manager dan aplikasi, permintaan yang tidak perlu tidak dibuat.



Bukan tanpa masalah: beberapa plugin chrome (CryptoPro, redux devtools) berhenti bekerja di aplikasi yang diunduh, karena tautan ke jendela hilang selama interaksi. Perbaikan tambahan diperlukan.



Hasilnya, pada akhir 2019, kami berhasil mentransfer semua aplikasi ke Frame Manager, dan sidebar telah terlupakan. Tetapi pekerjaan pada Manajer Bingkai berlanjut, dan sebuah pertanyaan baru muncul: apakah mungkin untuk meningkatkan dan mengoptimalkan pekerjaan frontend di Tinkoff Business? Ternyata Anda bisa! Tetapi lebih dari itu di artikel berikutnya.



All Articles