Mengapa Perlu Sistem Build?

Laporkan masalah Lihat sumber

Halaman ini membahas definisi sistem build, fungsinya, alasan Anda harus menggunakan sistem build, serta alasan compiler dan skrip build bukan pilihan terbaik saat organisasi Anda mulai melakukan penskalaan. Ini ditujukan bagi developer yang tidak memiliki banyak pengalaman dengan sistem build.

Apa itu sistem build?

Pada dasarnya, semua sistem build memiliki tujuan yang sederhana: sistem ini mengubah kode sumber yang ditulis oleh engineer menjadi biner yang dapat dieksekusi yang dapat dibaca oleh mesin. Sistem build tidak hanya untuk kode yang ditulis manusia, tetapi juga memungkinkan mesin membuat build secara otomatis, baik untuk pengujian atau rilis hingga produksi. Dalam organisasi yang memiliki ribuan engineer, biasanya sebagian besar build dipicu secara otomatis, bukan langsung oleh engineer.

Tidak bisakah saya hanya menggunakan compiler?

Kebutuhan akan sistem build mungkin tidak selalu terlihat jelas. Sebagian besar engineer tidak menggunakan sistem build saat mempelajari kode: sebagian besar engineer memulai dengan memanggil alat seperti gcc atau javac langsung dari command line, atau alat yang setara dalam lingkungan pengembangan terintegrasi (IDE). Selama semua kode sumber berada di direktori yang sama, perintah seperti ini akan berfungsi dengan baik:

javac *.java

Tindakan ini akan memerintahkan compiler Java untuk mengambil setiap file sumber Java dalam direktori saat ini dan mengubahnya menjadi file class biner. Dalam kasus paling sederhana, hanya inilah yang Anda butuhkan.

Namun, segera setelah kode diperluas, detail akan dimulai. javac cukup cerdas untuk melihat di subdirektori direktori saat ini guna menemukan kode untuk diimpor. Namun, project tidak dapat menemukan kode yang tersimpan di bagian lain sistem file (mungkin library yang digunakan bersama oleh beberapa project). Anda juga hanya tahu cara mem-build kode Java. Sistem besar sering kali melibatkan bagian berbeda yang ditulis dalam berbagai bahasa pemrograman dengan web dependensi di antara bagian-bagian tersebut, yang berarti tidak ada compiler untuk satu bahasa yang dapat mem-build seluruh sistem.

Setelah Anda menangani kode dari beberapa bahasa atau beberapa unit kompilasi, membangun kode tidak lagi memerlukan proses satu langkah. Sekarang Anda harus mengevaluasi apa yang menjadi dependensi kode Anda dan mem-build bagian-bagian tersebut dalam urutan yang tepat, mungkin menggunakan rangkaian alat yang berbeda untuk setiap bagian. Jika dependensi berubah, Anda harus mengulangi proses ini untuk menghindari ketergantungan pada biner yang sudah tidak berlaku. Untuk codebase dengan ukuran bahkan sedang, proses ini cepat menjadi membosankan dan rentan error.

Compiler juga tidak mengetahui apa pun tentang cara menangani dependensi eksternal, seperti file JAR pihak ketiga di Java. Tanpa sistem build, Anda dapat mengelola hal ini dengan mendownload dependensi dari internet, menempelkannya di folder lib pada hard drive, dan mengonfigurasi compiler untuk membaca library dari direktori tersebut. Seiring waktu, sulit untuk mempertahankan update, versi, dan sumber dependensi eksternal ini.

Bagaimana dengan skrip shell?

Misalkan project hobi Anda dimulai dengan cukup sederhana sehingga Anda dapat membangunnya hanya menggunakan compiler, tetapi Anda mulai mengalami beberapa masalah yang dijelaskan sebelumnya. Mungkin Anda masih tidak merasa memerlukan sistem build dan dapat mengotomatiskan bagian-bagian yang membosankan menggunakan beberapa skrip shell sederhana yang menangani build dalam urutan yang benar. Ini membantu untuk sementara waktu, tetapi segera Anda mulai mengalami lebih banyak masalah:

  • Hal ini melelahkan. Ketika sistem Anda berkembang menjadi lebih kompleks, Anda mulai menghabiskan banyak waktu untuk mengerjakan skrip build seperti pada kode sebenarnya. Proses debug skrip shell sangat merepotkan, dengan semakin banyak peretasan yang disusun sekaligus di atas satu sama lain.

  • Ini terlalu pelan. Untuk memastikan Anda tidak mengandalkan library yang sudah tidak berlaku secara tidak sengaja, Anda harus mengatur agar skrip build mem-build setiap dependensi secara berurutan setiap kali Anda menjalankannya. Anda mempertimbangkan untuk menambahkan beberapa logika untuk mendeteksi bagian mana yang perlu dibuat ulang, tetapi kedengarannya sangat rumit dan rentan error untuk suatu skrip. Atau, Anda berpikir untuk menentukan bagian mana yang perlu dibuat ulang setiap saat, tetapi Anda kembali ke tahap awal.

  • Kabar baik: kini saatnya merilis laporan! Sebaiknya cari tahu semua argumen yang perlu Anda teruskan ke perintah jar untuk membuat build akhir. Dan ingat cara menguploadnya dan mengirimnya ke repositori pusat. Kemudian, buat dan kirim pembaruan dokumentasi, serta kirimkan notifikasi kepada pengguna. Hmm, mungkin ini membutuhkan skrip lain...

  • Gawat! Hard drive Anda error, dan sekarang Anda harus membuat ulang seluruh sistem. Anda cukup pintar untuk menyimpan semua file sumber di kontrol versi, tetapi bagaimana dengan library yang Anda download? Dapatkah Anda menemukan semuanya lagi dan memastikan semuanya sama dengan versi saat Anda pertama kali mendownloadnya? Skrip Anda mungkin bergantung pada alat tertentu yang diinstal di tempat tertentu. Dapatkah Anda memulihkan lingkungan yang sama tersebut sehingga skrip berfungsi lagi? Bagaimana dengan semua variabel lingkungan yang sudah lama Anda tetapkan agar compiler-nya berfungsi dengan benar lalu terlupakan?

  • Terlepas dari masalah yang ada, proyek Anda cukup sukses sehingga Anda dapat mulai mempekerjakan lebih banyak engineer. Sekarang, Anda menyadari bahwa tidak diperlukan bencana untuk memunculkan masalah sebelumnya—Anda harus melalui proses bootstrap yang sama setiap kali developer baru bergabung dengan tim Anda. Meskipun sudah berupaya sebaik mungkin, masih ada perbedaan kecil pada sistem setiap orang. Sering kali, apa yang berfungsi di komputer seseorang tidak berfungsi di komputer orang lain, dan setiap kali dibutuhkan beberapa jam untuk men-debug jalur alat atau versi library untuk mencari tahu apa perbedaannya.

  • Anda memutuskan bahwa Anda perlu mengotomatiskan sistem build. Secara teori, langkah ini semudah mendapatkan komputer baru dan menyiapkannya untuk menjalankan skrip build Anda setiap malam menggunakan cron. Anda masih harus melalui proses penyiapan yang menyakitkan, tetapi sekarang Anda tidak diuntungkan karena otak manusia dapat mendeteksi dan menyelesaikan masalah kecil. Sekarang, setiap pagi saat Anda masuk, Anda melihat bahwa build tadi malam gagal karena kemarin developer melakukan perubahan yang berfungsi pada sistem mereka tetapi tidak berfungsi pada sistem build otomatis. Setiap kali perbaikannya sederhana, tetapi sering terjadi sehingga Anda akhirnya menghabiskan banyak waktu setiap hari untuk menemukan dan menerapkan perbaikan sederhana ini.

  • Build menjadi lebih lambat dan lebih lambat seiring pertumbuhan project. Suatu hari, selagi menunggu build selesai, Anda menatap desktop rekan kerja Anda yang sedang tidak aktif, yang sedang berlibur, dan berharap ada cara untuk memanfaatkan semua daya komputasi yang terbuang sia-sia.

Anda telah menghadapi masalah klasik mengenai skala. Untuk satu developer yang mengerjakan maksimum beberapa ratus baris kode paling lama satu atau dua minggu (yang sejauh ini mungkin merupakan seluruh pengalaman dari developer junior yang baru saja lulus universitas), compiler adalah yang Anda butuhkan. Skrip mungkin dapat membawa Anda sedikit lebih jauh. Namun, segera setelah Anda perlu berkoordinasi dengan beberapa developer dan mesinnya, skrip build yang sempurna pun tidak cukup karena akan sangat sulit untuk memperhitungkan perbedaan kecil pada mesin tersebut. Pada tahap ini, pendekatan sederhana ini sudah selesai dan kini saatnya untuk berinvestasi pada sistem build yang sebenarnya.