Kami menerbitkan terjemahan artikel, yang menjelaskan secara detail kerja jangka panjang tim untuk membuat dan memelihara portal data besar di JavaScript.
Pada 2019, sebuah artikel ditulis tentang Memelihara aplikasi JavaScript yang besar. Sebagai kelanjutan dari materi ini, kami ingin membagikan proyek klien yang telah didukung oleh tim saya sejak 2014.
Portal data untuk Organisasi untuk Kerja Sama dan Pembangunan Ekonomi (OECD)
Halaman muka portal
Organisasi untuk Kerja Sama dan Pembangunan Ekonomi adalah badan antar pemerintah yang mengumpulkan data dan menerbitkan penelitian atas nama negara anggotanya. Portal organisasi berisi informasi dari berbagai bidang: ekonomi, ekologi, pendidikan, dll
. Portal data OECD adalah gudang utama data statistik. Ini membantu peneliti, jurnalis, dan pembuat kebijakan menemukan informasi penting dan dengan cepat memvisualisasikannya menggunakan diagram. Portal OECD juga mengintegrasikan perpustakaan dengan publikasi iLibrary OECD , dan sumber daya OECD.Stat tempat semua data disimpan.
OECD didanai oleh negara anggota, yaitu para pembayar pajak seperti Anda dan saya. Salah satu persyaratan proyek adalah menggunakan teknologi yang hemat biaya dan andal, karena memelihara kode itu penting untuk waktu yang lama.
Portal data merupakan kolaborasi antara staf OECD dan pengembang serta desainer eksternal. Desain dan prototipe awal dibuat oleh Moritz Stefaner dan tim Raureif . Dan 9elements mengembangkan bagian front-end dan masih mempertahankannya.
Basis kode JavaScript yang kompleks
Bagian tersulit dari frontend di portal ini adalah mesin charting JavaScript. Ini berisi sepuluh jenis grafik utama dengan banyak opsi konfigurasi. Dengan menggunakan antarmuka yang kuat, pengguna dapat meminta database dan membuat diagram untuk disematkan atau dibagikan.
Kami mulai mengerjakan portal data pada tahun 2014. Sejak itu, ia tidak banyak ditulis ulang, hanya fitur baru yang ditambahkan, perbaikan kecil dan pemfaktoran ulang kode. Pada Desember 2020, kami menambahkan beberapa fitur baru untuk laporan Outlook Ekonomi OECD , termasuk empat jenis bagan lainnya. Kami juga mengatur ulang basis kode secara signifikan kali ini.
Di artikel ini, saya akan menunjukkan kepada Anda bagaimana kami mengelola untuk mempertahankan kode begitu lama dan memperbaikinya selangkah demi selangkah. Saya juga akan mengungkapkan apa yang tidak berhasil.
Teknologi mainstream yang membosankan
Proyek ini dimulai pada tahun 2014 dan saat itulah kami memilih HTML biasa, template XSLT, Sass untuk gaya tabel, dan CoffeeScript sebagai bahasa yang dikompilasi dengan JavaScript. Kami memilih jQuery, D3, D3.chart dan Backbone sebagai pustaka JavaScript.
Pada tahun 2014, teknologi ini adalah yang paling aman dan paling dapat dioperasikan, dari semuanya, memilih CoffeeScript adalah pertaruhan yang berisiko. Berkat CoffeeScript, kami dapat menjadi lebih produktif dan telah menulis kode yang andal. Tetapi kami tahu bahwa teknologi baru ini bisa jadi sulit.
Sejak 2015 tim 9elementsmulai menggunakan React untuk sebagian besar aplikasi web JavaScript. Kami berpikir untuk menggunakan React untuk versi baru mesin charting, tetapi semua orang tidak dapat menemukan momen yang tepat. Hasilnya, ternyata berpegang pada tumpukan teknologi asli adalah keputusan yang tepat.
Tumpukan JavaScript yang baru saja dijelaskan mungkin tampak ketinggalan jaman, tetapi pada kenyataannya, basis kode telah teruji oleh waktu. Salah satu alasannya: teknologi yang kami pilih masih relevan.
Pengaruh waktu yang merusak
Banyak pustaka JavaScript telah datang dan pergi, tetapi jQuery masih yang paling populer. Ini dapat diandalkan, didukung dengan baik, dan tersebar luas. Menurut Web Almanac 2020 , jQuery digunakan oleh 83% dari semua situs web. (Sebagai perbandingan, React hanya ditemukan pada 4%.)
Tentu saja, jQuery telah kehilangan posisi kepemimpinannya dalam menangani masalah DOM yang kompleks. Seperti yang disebutkan, saat ini kami akan memilih React atau Preact untuk membuat portal data tersebut.
Perpustakaan kedua, D3tetap menjadi standar untuk visualisasi data di browser. Itu sudah ada sejak 2010 dan masih menjadi yang terdepan. Meskipun beberapa rilis utama telah mengubah struktur dan API secara signifikan, D3 masih merupakan rekayasa yang luar biasa.
Perpustakaan Backbone tidak begitu populer, tetapi memiliki kelebihan. Misalnya, ini relatif sederhana: Anda dapat membaca kode sumber di suatu pagi dan mengulang bagian utama dalam sehari. Ditambah lagi, Backbone masih didukung. Ini berfungsi penuh, yang sangat penting.
Dari sudut pandang teknologi, hanya CoffeeScript bukanlah teknologi yang relevan dalam kenyataan saat ini. Bahasa ini dikembangkan karena kekurangan yang jelas dalam ECMAScript 5. Kemudian, banyak ide dari CoffeeScript dimasukkan ke dalam standar ECMAScript 6 (2015) dan ECMAScript 7 (2016). Mulai sekarang, kami tidak punya alasan untuk menggunakannya.
Kami memilih CoffeeScript pada tahun 2014 karena filosofi "Ini hanya JavaScript". Tidak seperti bahasa lain yang dikompilasi dengan JavaScript, CoffeeScript adalah abstraksi langsung. CoffeeScript mengkompilasi ke JavaScript murni tanpa kejutan.
Sebagian besar perusahaan saat ini telah memigrasikan basis kode mereka dari CoffeeScript ke JavaScript modern. Dan kami melakukan hal yang sama.
Dari CoffeeScript ke TypeScript
Dengan alat dekafinasi ini , kami mengonversi kode CoffeeScript ke ECMAScript 6 (2015). Kami ingin terus mendukung browser yang sama, jadi kami sekarang menggunakan compiler Babel untuk membuat ECMAScript yang kompatibel dengan
versi sebelumnya 5. Secara keseluruhan, transisi berjalan lancar, tetapi kami tidak ingin berhenti di situ.
Dalam proyek baru, pengembang 9elements menggunakan TypeScript. Menurut pendapat saya, TypeScript adalah hal terbaik yang telah terjadi di dunia JavaScript dalam beberapa tahun terakhir. Seperti yang saya sebutkan di artikel saya sebelumnya, TypeScript membuat Anda berpikir tentang jenis dan mengajari Anda untuk menamainya dengan benar.
Untuk portal data kami, kami akan memanfaatkan TypeScript tanpa mengubah basis kode menjadi TypeScript yang sepenuhnya diketik.
TypeScript adalah superset dari JavaScript. Kompilator memahami file .js dengan baik. Oleh karena itu, kami secara bertahap menambahkan anotasi jenis menggunakan teknologi dari 20 tahun yang lalu - JSDOC . Selain itu, beberapa jenis (pengetikan) telah ditulis dalam file .ts untuk referensi mereka dalam penjelasan JSDOC.
Dengan demikian, pengalaman pengembangan dalam Visual Studio Code telah berkembang secara signifikan tanpa banyak usaha. Meskipun tidak ada pemeriksaan tipe yang ketat di sini, mengedit kode semudah dalam proyek TypeScript biasa.
Dengan menggabungkan teknologi yang agak membosankan tetapi kuat dengan compiler TypeScript terbaru, kami dapat menambahkan fitur baru dan kode refactor dengan aman dan mudah.
Dokumentasi dan komentar kode
Di permukaan, coding adalah percakapan antara Anda dan komputer: Anda memberi tahu komputer apa yang perlu dilakukan.
Namun pada kenyataannya, coding adalah percakapan antara Anda dan pembaca kode. Sudah diketahui umum bahwa kode ditulis sekali dan dibaca berulang kali. Pertama-tama, Anda menulis kode untuk diri Anda di masa depan.
Kami telah menambahkan banyak komentar ke basis kode portal, dan hampir semuanya telah berhasil membuktikan nilainya selama enam tahun terakhir. Jelas, kode harus disusun sedemikian rupa untuk membantu pembaca memahaminya. Tapi saya tidak percaya pada kode "yang mendeskripsikan diri" atau "mendokumentasikan diri".
Sebelum pindah ke JSDOC, kami membuat anotasi tipe yang mudah dibaca, parameter fungsi terdokumentasi, dan nilai kembalian. Kami juga telah mendokumentasikan tipe data dasar dan struktur objek bersarang yang kompleks.
Komentar ini sangat membantu enam tahun kemudian. Kami menerjemahkannya ke dalam JSDOC yang dapat dibaca mesin dan deklarasi tipe untuk compiler TypeScript.
Hal-hal rusak - selalu siapkan rangkaian pengujian
Proyek ini hanya memiliki beberapa pengujian unit otomatis dan lebih dari 50 (!) Halaman pengujian yang mendemonstrasikan semua halaman portal, komponen, antarmuka kueri data, jenis bagan dan pengaturan. Mereka menguji data langsung, pementasan, dan tiruan.
Halaman pengujian ini melakukan hal yang sama seperti pengujian otomatis: jika kami memperbaiki bug, pertama-tama kami menambahkan skrip ke halaman pengujian yang sesuai. Jika kami sedang mengembangkan fitur baru, pada saat yang sama kami membuat halaman pengujian lengkap.
Halaman pengujian
Sebelum rilis, kami memeriksa semua halaman pengujian secara manual dan membandingkannya dengan yang terakhir secara visual dan fungsional. Ini memakan waktu, tetapi memungkinkan Anda menemukan regresi dengan cepat.
Saya tidak berpikir rangkaian pengujian otomatis akan lebih efisien. Hampir tidak mungkin untuk menguji visualisasi data interaktif di browser secara otomatis. Pengujian regresi visual adalah alat yang berharga, tetapi dalam kasus kami ini dapat memberikan terlalu banyak kesalahan palsu.
Kompatibilitas mundur dan maju
Pada tahun 2014, portal kami seharusnya dapat berfungsi dengan Internet Explorer 9. Sekarang Internet Explorer tidak begitu penting, terutama saat membuat mesin dinamis untuk membuat plot di browser.
Namun, kami memutuskan untuk tetap kompatibel dengan browser lama. Portal data adalah platform internasional tempat pengguna dari seluruh dunia berkunjung. Tidak semua orang memiliki komputer dan browser terbaru.
Portal di Internet Explorer 9
Kami mampu mempertahankan tingkat dasar dukungan browser dengan menggunakan teknologi standar yang membosankan. Tentu saja, ada juga beberapa fitur web modern, tetapi kami hanya mengaktifkannya jika browser mendukungnya. Di sinilah pendekatan Peningkatan Progresif membantu kami. (peningkatan progresif). Kami juga menggunakan Babel dan polyfills untuk membuat fungsi JavaScript modern berfungsi di peramban lama.
Abstraksi Anda mungkin menggigit
Selama bertahun-tahun, kami tidak dibatasi oleh tumpukan teknologi. Sebaliknya, abstraksi mereka sendiri menghalangi.
Kami membagi antarmuka pengguna menjadi beberapa bagian visual (tampilan) dan membuat kelas dasar yang mirip dengan Backbone.View. (Saat ini, semua pustaka JavaScript besar menggunakan istilah "komponen" daripada "tampilan" untuk bagian antarmuka pengguna.) Kami menggunakan Backbone.Model untuk menyimpan data dan status. Ini berhasil dengan baik, tetapi kami memutuskan untuk tetap menggunakan praktik terbaik kami sendiri.
Ide di balik pemisahan tampilan model Backbone adalah bahwa model ini adalah satu-satunya sumber kebenaran. DOM seharusnya hanya mencerminkan data model. Semua perubahan juga harus datang dari modelnya. Kerangka kerja modern seperti React, Vue, dan Angular mengikuti konvensi bahwa UI adalah "fungsi status", yang berarti UI merupakan turunan dari status.
Kami melanggar prinsip ini dan terkadang menjadikan DOM sebagai sumber kebenaran. Hal ini menyebabkan kebingungan dengan kode yang memandang model sebagai sumber otoritatif.
Grafik berorientasi objek
Untuk bagan, kami mengambil pendekatan yang berbeda: kami membuat kelas bagan yang berbeda dari yang dijelaskan di atas.
D3 itu sendiri berfungsi. Bagan biasanya dibuat dan diperbarui dengan fungsi render yang memanggil fungsi lain. Diagram berikut merupakan pengantar untuk fitur hebat ini. Lebih banyak status terkandung dalam objek tertentu.
Ini membuat D3 ekspresif dan fleksibel. Tetapi kode D3 sulit dibaca karena ada sedikit konvensi (konvensi yang tidak didokumentasikan) untuk menangani struktur bagan.
Irene Ros dan Mike Pennisi, developer di Bocoup, menemukan d3.chart, library kecil di atas D3 yang mewakili OOP berbasis kelas. Tujuan utamanya adalah untuk menyusun dan menggunakan kembali kode charting. Diagram ini terdiri dari beberapa lapisan, yang masing-masing merender dan memperbarui bagian tertentu dari DOM menggunakan D3. Selain itu, diagram lain dapat dilampirkan ke bagan.
Aturan umum OOP adalah "Komposisi menang atas warisan." Sayangnya, kami memilih kombinasi komposisi dan pewarisan yang aneh untuk perilaku diagram.
Kami perlu menggunakan fungsi atau kelas sederhana daripada hierarki kelas yang kompleks. Orang-orang masih membungkus D3 dalam OOP berbasis kelas, tetapi tidak ada solusi berbasis kelas yang mampu mengungguli struktur fungsional D3.
Mari kita simpulkan
Sejak kami mengembangkan bagian front-end portal data pada tahun 2014, ada banyak pendekatan keren untuk membuat antarmuka web berbasis JavaScript.
Sekarang komponen UI bersifat deklaratif, Anda dapat melakukannya tanpa merender template HTML dan memperbarui DOM secara manual. Anda baru saja memperbarui status dan kerangka kerja memperbarui DOM. Aliran data searah ini menghilangkan seluruh kelas bug.
Teknologi yang kami pilih pada tahun 2014 dapat bertahan dalam ujian waktu atau membuatnya mudah untuk beralih ke tumpukan yang berbeda. Anda mungkin berpikir kami beruntung, tetapi kami sengaja membuat pilihan yang mendukung teknologi yang tahan lama.
Di 9elements kami selalu mencoba menggunakan teknologi modern, termasuk mengevaluasi teknologi front-end eksperimental yang mungkin tidak relevan dalam 3-4 tahun. Sayangnya, banyak proyek JavaScript open source yang secara teknis progresif, tetapi tidak stabil.
Untuk setiap proyek, kami mencari keseimbangan optimal antara teknologi berkelanjutan dengan risiko minimal dan tumpukan inovatif, yang membantu kami menciptakan produk berkualitas.