Monorepo memudahkan beberapa aplikasi dan library dikerjakan dalam satu repository. Namun, kedekatan lokasi kode perlu dibedakan dari kebutuhan untuk selalu membangun dan merilis semuanya bersama.
Dua hari lalu, saya memisahkan aplikasi portal dari susunan workspace sebelumnya. Perubahan ini membawa saya kembali pada satu pertanyaan: bagian mana yang memang perlu berubah bersama, dan bagian mana yang sebaiknya dapat berjalan sendiri?
Menilai hubungan antarbagian
Manfaat monorepo yang biasa disebut, termasuk di dokumentasi Nx, adalah penggunaan ulang kode dan perubahan beberapa bagian dalam satu commit. Manfaat itu terasa ketika aplikasi memakai kontrak, komponen, atau tipe yang sama.
Sebagai contoh umum, perubahan bentuk data API dapat dikerjakan bersama penyesuaian pemakainya. Sebaliknya, bila sebuah aplikasi jarang berbagi kode dan memiliki kebutuhan rilis sendiri, alasan mempertahankannya dalam susunan yang sama perlu dinilai kembali.
Saya melihat pemisahan sebagai keputusan tentang tanggung jawab. Jumlah folder atau ukuran repository saja belum cukup untuk menjawabnya.
Peta pertimbangan
Pertimbangan | Pertanyaan sebelum memisahkan |
Kode bersama | Apa yang masih dipakai aplikasi lain, dan siapa yang merawatnya? |
Build | Bisakah aplikasi dibangun tanpa bergantung pada file yang tidak ikut dibawa? |
Rilis | Apakah aplikasi perlu versi dan jadwal rilis sendiri? |
Pemeliharaan | Apakah pemisahan memperjelas tanggung jawab atau justru menggandakan pekerjaan? |
Nx sendiri menyediakan pengaturan task dan dependency agar pekerjaan antarproject dapat diatur secara eksplisit.
Contoh dari perubahan aplikasi portal
Aplikasi portal yang saya kerjakan sebelumnya berada dalam workspace Nx dengan direktori
apps dan libs. Sekarang, aplikasi tersebut saya kelola secara mandiri di repository bolsel/portalweb.Susunannya kini memakai direktori
src, dengan perintah next dev, next build, dan next start langsung di package.json. Batas aplikasi menjadi lebih terlihat: kode, dependency, dan perintah untuk menjalankannya berada dalam satu project.Bagi saya, pemisahan ini belum selesai hanya karena file sudah berpindah. Build perlu diperiksa kembali, begitu juga kebutuhan runtime dan cara merilisnya. Jika ingin menilai pengaruhnya terhadap kecepatan atau biaya pemeliharaan, hasil sebelum dan sesudahnya perlu diukur.
Memisahkan repository juga memindahkan tanggung jawab
Saat kode keluar dari workspace, saya menyarankan pemeriksaan terhadap import internal, dependency, aset, dan perintah build. Sesuatu yang sebelumnya tersedia dari root workspace harus mempunyai sumber yang jelas di aplikasi tujuan.
Untuk kode yang masih dibagikan, pilihannya perlu dinyatakan: tetap menjadi paket dengan versi, dibawa menjadi bagian aplikasi, atau dihentikan pemakaiannya. Pilihan ini memiliki konsekuensi pemeliharaan. Menyalin sebuah library, misalnya, juga membuat perbaikannya perlu dikoordinasikan bila salinan lain masih digunakan.
Prinsip tersebut sejalan dengan pembahasan batas kode dalam dokumentasi Nx: kode yang diletakkan bersama tetap membutuhkan aturan penggunaan. Setelah dipisahkan, kebutuhan akan batas yang jelas juga tetap ada.
Dua arti standalone
Istilah standalone perlu digunakan dengan hati-hati. Pada contoh tadi, istilah itu menjelaskan aplikasi yang dikelola sendiri. Sementara itu,
output: 'standalone' pada Next.js 13.4 adalah pilihan untuk menghasilkan folder deployment berisi file runtime yang ditelusuri saat build.Keduanya berada pada lapisan berbeda. Mengaktifkan pilihan output Next.js tidak memindahkan aplikasi keluar dari monorepo. Sebaliknya, memisahkan repository tidak otomatis mengaktifkan pilihan output tersebut.
Dokumentasi versi itu juga menjelaskan batas penelusuran file pada monorepo. Karena itu, hasil build perlu diuji dengan susunan file yang benar-benar akan digunakan untuk menjalankan aplikasi.
Memulai dari batas yang paling jelas
Saya menyarankan urutan sederhana: petakan kode bersama, periksa dependency build, tentukan tanggung jawab rilis, lalu uji aplikasi dalam lingkungan yang hanya berisi kebutuhan yang dinyatakan.
Monorepo tetap berguna ketika perubahan antarbagian perlu dikoordinasikan. Pemisahan juga masuk akal ketika membuat batas aplikasi lebih jelas. Ukurannya sederhana: apakah setelah dipisah, build dan rilis lebih mudah dijelaskan daripada sebelumnya?
