Mengoptimalkan Monorepo Anda: Panduan Praktis dengan Nx dan Turborepo
1. Pendahuluan
Jika Anda sudah membaca artikel saya tentang “Monorepos: Mengelola Proyek Multi-Aplikasi dengan Efisien”, Anda pasti sudah familiar dengan konsep monorepo. Singkatnya, monorepo adalah strategi di mana Anda menyimpan beberapa proyek (misalnya, frontend, backend, library UI, shared utilities) dalam satu repositori Git yang besar.
Monorepo menawarkan banyak keuntungan: kode yang bisa dibagi pakai, manajemen dependensi yang terpusat, dan penyederhanaan proses deployment. Ini terdengar seperti mimpi bagi banyak tim pengembangan, terutama yang bekerja dengan arsitektur mikroservis atau micro-frontend.
Namun, monorepo juga datang dengan tantangannya sendiri. Bayangkan Anda punya puluhan proyek dalam satu repo. Setiap kali Anda mengubah satu baris kode di sebuah library kecil, apakah Anda harus me-build dan menguji semua proyek yang ada? Tentu saja tidak! Itu akan sangat memakan waktu, menguras resource, dan membuat developer frustrasi.
Di sinilah alat bantu khusus monorepo seperti Nx dan Turborepo berperan. Mereka adalah pahlawan tanpa tanda jasa yang mengubah potensi kekacauan monorepo menjadi orkestrasi yang mulus dan efisien. Artikel ini akan membawa Anda menyelami dunia alat-alat canggih ini, memahami cara kerjanya, membandingkannya, dan bagaimana Anda bisa menggunakannya untuk mengoptimalkan monorepo Anda. Mari kita mulai!
2. Mengapa Monorepo Membutuhkan Alat Khusus?
Mungkin Anda berpikir, “Bukankah npm workspaces atau yarn workspaces sudah cukup untuk monorepo?” Ya, mereka memang menyediakan fondasi dasar untuk mengelola banyak paket dalam satu repositori. Tapi, untuk monorepo skala menengah hingga besar, Anda akan segera menghadapi beberapa masalah pelik:
- Build dan Test yang Lambat: Tanpa alat khusus, setiap perintah
buildatautestsering kali akan dijalankan untuk semua proyek di dalam monorepo, bahkan jika hanya satu proyek yang berubah. Ini membuang waktu dan resource komputasi. - Manajemen Dependensi yang Kompleks: Melacak dependensi internal antar-proyek dan dependensi eksternal bisa menjadi mimpi buruk. Bagaimana Anda memastikan bahwa setiap proyek menggunakan versi library internal yang paling mutakhir?
- Konsistensi Konfigurasi: Memastikan setiap proyek memiliki konfigurasi linter, formatter, TypeScript, atau build tool yang konsisten bisa sangat melelahkan.
- Developer Experience (DX) yang Buruk: Developer harus menunggu lama untuk build, test, atau menjalankan perintah lainnya. Ini menurunkan produktivitas dan motivasi.
📌 Intinya: Alat seperti Nx dan Turborepo hadir untuk mengatasi masalah performa, kompleksitas, dan DX yang melekat pada monorepo tanpa optimasi. Mereka menyediakan “kecerdasan” yang dibutuhkan untuk membuat monorepo benar-benar efisien.
3. Mengenal Nx: Sang Arsitek Monorepo Anda
Nx adalah framework monorepo yang komprehensif dari Narwhal. Nx bukan hanya sekadar build tool; ia adalah ekosistem lengkap yang membantu Anda mendesain, membangun, dan memelihara monorepo dengan berbagai jenis proyek, mulai dari frontend (React, Angular, Vue), backend (Node.js, NestJS, Express), hingga library dan shared utilities.
Fitur Utama Nx:
- Graph-based Task Execution: Ini adalah inti kecerdasan Nx. Nx membangun sebuah “dependency graph” dari semua proyek di monorepo Anda. Ketika Anda menjalankan perintah seperti
nx build, Nx akan menganalisis graph ini dan hanya akan menjalankan ulang tugas untuk proyek-proyek yang benar-benar terpengaruh oleh perubahan yang Anda buat. - Intelligent Caching: Nx menyimpan hasil dari setiap tugas (build, test, lint) yang berhasil dijalankan. Jika Anda mencoba menjalankan tugas yang sama lagi dan inputnya tidak berubah, Nx akan langsung mengembalikan hasil dari cache, tanpa perlu menjalankan ulang. Ini berlaku baik secara lokal maupun di CI/CD.
- Plugins Ekstensif: Nx memiliki sistem plugin yang kuat untuk mengintegrasikan berbagai framework dan tool. Ada plugin resmi untuk React, Angular, Next.js, NestJS, Storybook, Jest, Cypress, dan banyak lagi. Ini menyediakan scaffolding, generator, dan konfigurasi yang sudah dioptimalkan.
- Code Generation: Dengan generator yang disediakan oleh plugin, Anda bisa dengan cepat membuat aplikasi baru, library, komponen, atau bahkan skema database dengan konfigurasi standar yang konsisten.
- Dependency Graph Visualization: Nx menyediakan perintah
nx graphyang bisa memvisualisasikan semua proyek dan dependensinya dalam bentuk diagram interaktif. Ini sangat membantu untuk memahami arsitektur monorepo Anda.
Contoh Sederhana dengan Nx:
Mari kita lihat bagaimana Nx bekerja.
-
Instalasi dan Pembuatan Workspace:
npx create-nx-workspace@latest my-monorepo --preset=react-standalone cd my-monorepoIni akan membuat workspace Nx baru dengan setup React dasar. Nx akan membuat struktur seperti:
my-monorepo/ ├── apps/ # Folder untuk aplikasi (misal: frontend, admin-panel) │ └── my-react-app ├── libs/ # Folder untuk library yang bisa dibagi pakai (misal: ui-components, data-access) ├── tools/ ├── nx.json # Konfigurasi Nx utama ├── package.json └── tsconfig.base.json -
Membuat Library Baru:
nx generate @nx/js:library shared-ui --project-name=shared-ui --directory=libs/shared/ui --no-interactivePerintah ini akan membuat library
shared-uidilibs/shared/ui. -
Membangun Aplikasi:
nx build my-react-appJika Anda menjalankan perintah ini untuk pertama kali, Nx akan membangun aplikasi. Jika Anda menjalankannya lagi tanpa perubahan, Nx akan langsung menggunakan cache.
-
Melihat Proyek yang Terpengaruh:
nx affected:buildSetelah Anda mengubah kode di
libs/shared/ui, perintahnx affected:buildakan mencari dan hanya me-build proyek yang terpengaruh oleh perubahan dishared-ui(misalnya,my-react-appjika ia menggunakanshared-ui).
💡 Tips Nx: Manfaatkan nx graph untuk memahami dependensi, dan nx affected:* untuk mempercepat development cycle Anda. Nx sangat cocok untuk tim yang membutuhkan konsistensi, scaffolding, dan dukungan multi-framework.
4. Mengenal Turborepo: Kecepatan Kilat untuk Monorepo Anda
Turborepo adalah build system monorepo yang fokus pada kecepatan, dikembangkan oleh Vercel. Berbeda dengan Nx yang merupakan framework komprehensif, Turborepo lebih “agnostik” dan fokus pada satu hal: membuat build dan test Anda di monorepo secepat mungkin. Turborepo bisa digunakan bersama dengan npm, yarn, atau pnpm workspaces.
Fitur Utama Turborepo:
- Content-Aware Hashing: Turborepo menganalisis konten file dari setiap proyek dan dependensinya. Ia membuat hash unik untuk setiap tugas. Jika hash ini tidak berubah (artinya, tidak ada perubahan relevan pada kode atau dependensi), Turborepo tidak akan menjalankan tugas tersebut dan akan menggunakan cache.
- Remote Caching: Ini adalah salah satu fitur unggulan Turborepo. Anda bisa mengkonfigurasi Turborepo untuk menyimpan dan mengambil cache dari server remote (misalnya, Vercel Remote Cache atau S3). Ini berarti hasil build dari CI/CD bisa dibagikan ke developer lokal, atau antar developer, sehingga mempercepat proses secara signifikan.
- Parallel Execution: Turborepo secara otomatis menjalankan tugas-tugas yang tidak memiliki dependensi satu sama lain secara paralel, memaksimalkan penggunaan core CPU Anda.
- Minimal Configuration: Turborepo sangat mudah diatur, terutama untuk monorepo berbasis JavaScript/TypeScript yang sudah menggunakan
workspaces. Konfigurasinya biasanya hanya berupa satu fileturbo.json. - Affected Commands (Implicit): Mirip dengan Nx, Turborepo secara implisit hanya akan menjalankan tugas untuk proyek yang terpengaruh, berkat sistem hashing cerdasnya.
Contoh Sederhana dengan Turborepo:
Mari kita lihat bagaimana Turborepo bekerja.
-
Setup Monorepo dengan Workspaces (misal, Yarn):
mkdir my-turbo-monorepo cd my-turbo-monorepo yarn init -y # Tambahkan "workspaces" ke package.json # { "name": "my-turbo-monorepo", "private": true, "workspaces": ["apps/*", "packages/*"] } mkdir apps packages cd apps && mkdir web && cd web && yarn init -y && cd ../.. cd packages && mkdir ui && cd ui && yarn init -y && cd ../..Sekarang Anda punya struktur dasar monorepo:
my-turbo-monorepo/ ├── apps/ │ └── web/ ├── packages/ │ └── ui/ ├── package.json └── yarn.lock -
Instalasi Turborepo:
yarn add turbo --dev -
Konfigurasi
turbo.json: Buat fileturbo.jsondi root monorepo Anda:// turbo.json { "$schema": "https://turbo.build/schema.json", "pipeline": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**", ".next/**"] }, "test": { "dependsOn": ["^build"], "outputs": [] }, "lint": { "outputs": [] }, "dev": { "cache": false, "persistent": true } } }dependsOn: Menentukan dependensi antar-tugas.^buildberarti tugasbuildini bergantung pada tugasbuilddari dependensi internal proyek.outputs: File/folder yang akan di-cache setelah tugas selesai.
-
Menambahkan Script ke
package.jsonmasing-masing proyek: Misalnya, diapps/web/package.json:// apps/web/package.json { "name": "web", "scripts": { "build": "next build", // Contoh, jika ini aplikasi Next.js "test": "jest", "lint": "eslint ." } }Dan di
packages/ui/package.json:// packages/ui/package.json { "name": "ui", "scripts": { "build": "tsc", // Contoh, jika ini library TypeScript "test": "jest", "lint": "eslint ." } } -
Menjalankan Tugas dengan Turbo:
turbo run buildPerintah ini akan menjalankan script
builddi semua proyek yang memiliki script tersebut, tetapi hanya jika ada perubahan yang relevan. Jika Anda menjalankannya lagi tanpa perubahan, Turbo akan langsung menggunakan cache.turbo run test --filter=webAnda juga bisa memfilter untuk menjalankan tugas hanya pada proyek tertentu.
✅ Kelebihan Turborepo: Kecepatan build yang luar biasa, konfigurasi minimal, dan remote caching yang powerful. Sangat cocok untuk monorepo JavaScript/TypeScript yang memprioritaskan performa dan kemudahan setup.
5. Nx vs. Turborepo: Memilih Jagoan Anda
Baik Nx maupun Turborepo adalah alat yang fantastis untuk monorepo, tetapi mereka memiliki filosofi dan fokus yang sedikit berbeda. Memilih di antara keduanya tergantung pada kebutuhan spesifik tim dan proyek Anda.
| Fitur/Aspek | Nx | Turborepo |
|---|---|---|
| Filosofi Utama | Framework monorepo komprehensif, opinionated, ekosistem plugin kaya. | Build system yang cepat, minimal config, agnostik, fokus ke performa. |
| Target Proyek | Multi-framework (React, Angular, Node, Go, dll.), multi-bahasa. | Umumnya JS/TS monorepo. |
| Kurva Pembelajaran | Lebih curam karena banyaknya konsep dan plugin. | Lebih landai, mudah diintegrasikan. |
| Scaffolding/Generator | Sangat kuat, banyak generator untuk aplikasi, library, komponen. | Tidak ada fitur scaffolding bawaan. |
| Analisis Dependensi | Dependency graph eksplisit, bisa divisualisasikan. | Content-aware hashing yang implisit. |
| Caching | Intelligent local caching. | Content-aware local & powerful remote caching. |
| Integrasi CI/CD | Mudah dengan Nx Cloud (opsional). | Sangat mudah, terutama dengan Vercel Remote Cache. |
| Ukuran Komunitas | Besar dan aktif. | Berkembang pesat, didukung Vercel. |
🎯 Kapan Memilih Nx?
- Jika Anda memiliki monorepo yang sangat besar dengan berbagai jenis proyek (frontend, backend, mobile, dll.) dan/atau menggunakan berbagai framework (misalnya, React, Angular, NestJS).
- Jika Anda membutuhkan konsistensi konfigurasi yang ketat dan ingin memanfaatkan fitur scaffolding/code generation untuk mempercepat pembuatan proyek baru.
- Jika tim Anda tidak keberatan dengan kurva pembelajaran yang sedikit lebih tinggi demi mendapatkan ekosistem yang sangat lengkap.
- Jika Anda membutuhkan visualisasi dependency graph yang mendalam.
🎯 Kapan Memilih Turborepo?
- Jika Anda memiliki monorepo yang fokus pada JavaScript/TypeScript dan prioritas utama Anda adalah kecepatan build dan test.
- Jika Anda menginginkan setup yang minimal dan cepat, tanpa banyak konfigurasi tambahan.
- Jika Anda sudah nyaman dengan
npm,yarn, ataupnpm workspacesdan ingin menambahkan lapisan performa di atasnya. - Jika Anda sangat mengandalkan remote caching untuk mempercepat CI/CD dan sharing cache antar developer.
⚠️ Penting: Dalam banyak kasus, Anda bahkan bisa mengkombinasikan keduanya! Misalnya, menggunakan Turborepo sebagai build system utama untuk kecepatan, tetapi tetap memanfaatkan generator dari plugin Nx untuk scaffolding jika Anda memerlukannya. Namun, untuk memulai, disarankan untuk fokus pada salah satu terlebih dahulu.
6. Praktik Terbaik Mengelola Monorepo dengan Tools Ini
Mengadopsi Nx atau Turborepo saja tidak cukup. Anda juga perlu menerapkan praktik terbaik untuk benar-benar memaksimalkan potensi monorepo Anda:
-
Struktur Direktori yang Jelas:
- Gunakan
apps/untuk aplikasi yang bisa di-deploy (misalnya,apps/web,apps/api,apps/admin). - Gunakan
libs/ataupackages/untuk library yang bisa dibagi pakai (misalnya,libs/ui,libs/data-access,libs/utils). - Pertahankan konsistensi dalam penamaan dan organisasi.
- Gunakan
-
Granularitas Library yang Tepat:
- Jangan membuat library yang terlalu besar. Pecah fungsionalitas menjadi library-library kecil yang fokus pada satu tujuan (misalnya,
libs/ui/button,libs/ui/carddaripadalibs/ui-componentsyang besar). Ini memaksimalkan caching dan meminimalkan ketergantungan.
- Jangan membuat library yang terlalu besar. Pecah fungsionalitas menjadi library-library kecil yang fokus pada satu tujuan (misalnya,
-
Manfaatkan Caching Sepenuhnya:
- Pastikan output dari setiap tugas (build, test) didefinisikan dengan benar dalam konfigurasi (
nx.jsonatauturbo.json) sehingga hasil bisa di-cache. - Untuk Turborepo, pertimbangkan untuk mengaktifkan remote caching untuk manfaat yang lebih besar di lingkungan tim dan CI/CD.
- Pastikan output dari setiap tugas (build, test) didefinisikan dengan benar dalam konfigurasi (
-
Pipelining Tugas yang Efisien:
- Definisikan dependensi tugas dengan cermat. Misalnya,
testbergantung padabuildyang berhasil,deploybergantung padabuilddantestyang berhasil. Ini memastikan urutan eksekusi yang benar dan menghindari pekerjaan yang tidak perlu.
- Definisikan dependensi tugas dengan cermat. Misalnya,
-
Integrasi CI/CD yang Cerdas:
- Integrasikan tools monorepo Anda ke pipeline CI/CD. Gunakan perintah
affected:(Nx) atauturbo rundenganfilter(Turborepo) untuk hanya menjalankan pipeline pada proyek yang benar-benar berubah. - Manfaatkan remote caching di CI/CD untuk mempercepat build dan test.
- Integrasikan tools monorepo Anda ke pipeline CI/CD. Gunakan perintah
-
Konsistensi Tools dan Konfigurasi:
- Gunakan Prettier, ESLint, TypeScript, dan Jest secara konsisten di seluruh monorepo. Tools monorepo seperti Nx sering menyediakan plugin untuk membantu hal ini.
- Terapkan
lint-stageddanhuskyuntuk memastikan kode yang di-commit selalu bersih dan sesuai standar.
-
Dokumentasi yang Baik:
- Meskipun tools ini otomatis, dokumentasikan struktur monorepo Anda, cara menjalankan perintah, dan praktik terbaik yang disepakati tim. Ini penting untuk onboarding developer baru.
Kesimpulan
Monorepo adalah strategi pengembangan yang kuat, tetapi efisiensinya sangat bergantung pada alat yang Anda gunakan. Nx dan Turborepo adalah dua solusi terdepan yang masing-masing menawarkan pendekatan unik untuk mengatasi tantangan monorepo.
Nx adalah pilihan tepat jika Anda mencari framework monorepo yang komprehensif, dengan dukungan multi-framework, scaffolding yang kuat, dan visualisasi dependensi yang mendalam. Ini seperti memiliki seorang arsitek yang membantu Anda merancang dan membangun struktur monorepo Anda dari awal.
Di sisi lain, Turborepo adalah pilihan ideal jika Anda memprioritaskan kecepatan build yang ekstrem, konfigurasi minimal, dan fitur remote caching yang powerful, terutama untuk monorepo berbasis JavaScript/TypeScript. Ini seperti memiliki mesin balap yang sangat cepat dan efisien untuk menjalankan semua tugas Anda.
Mana pun yang Anda pilih, atau bahkan jika Anda memutuskan untuk mengkombinasikan beberapa fiturnya, menginvestasikan waktu untuk memahami dan mengimplementasikan alat-alat ini akan secara signifikan meningkatkan Developer Experience, mempercepat siklus pengembangan, dan membuat monorepo Anda menjadi aset yang jauh lebih produktif dan mudah dikelola. Selamat mencoba!
🔗 Baca Juga
- Monorepos: Mengelola Proyek Multi-Aplikasi dengan Efisien
- Memilih dan Mengimplementasikan Headless CMS: Fondasi Konten Fleksibel untuk Aplikasi Modern Anda
- Server-Sent Events (SSE): Membangun Fitur Real-time Satu Arah dengan Mudah
- Micro-Frontends: Membangun Frontend yang Skalabel dan Mandiri dengan Pendekatan Microservices