𝗟𝗲𝗯𝗶𝗵 𝗱𝗮𝗿𝗶 𝗦𝗲𝗸𝗮𝗱𝗮𝗿 𝗘𝗸𝘀𝗽𝗼𝗿 𝘆𝗮𝗻𝗴 𝗛𝗶𝗹𝗮𝗻𝗴: 𝗠𝗲𝗺𝗯𝗮𝗻𝗴𝘂𝗻 𝗘𝗮𝗿𝗹𝘆 𝗚𝗮𝗿𝗯𝗮𝗴𝗲 𝗖𝗼𝗹𝗹𝗲𝗰𝘁𝗼𝗿

Saya mencoba menggunakan plugin standar untuk memperbaiki tautan yang hilang dalam dokumentasi Webpack. Namun, cara tersebut gagal.

Mengintegrasikan plugin ke dalam basis kode yang besar bukanlah tugas yang mudah. Hal ini menjadi tantangan arsitektural. Saya harus mengelola manipulasi Abstract Syntax Tree (AST), penggunaan memori, dan loop rekursif.

Masalah dengan Plugin Standar

Saya menjalankan tiga eksperimen untuk menemukan solusi.

Eksperimen 1: Plugin tersebut berhasil memulihkan 135 tipe. Namun, plugin tersebut menempatkannya dalam modul internal. Alat kami membuat folder terpisah untuk tipe-tipe tersebut. Kami harus menyortirnya secara manual. Dokumentasinya juga salah secara struktural.

Eksperimen 2: Saya mengaktifkan pengaturan untuk menyembunyikan tipe eksternal. Ini berhasil untuk beberapa hal. Hal ini mengurangi payload menjadi 60 tipe Webpack. Namun, TypeDoc mengabaikan dependensi bersarang (nested dependencies). Hal ini menyebabkan banyak tipe tetap tersembunyi padahal masih menggunakan memori.

Eksperimen 3: Saya mencoba memetakan kembali tipe-tipe tersebut ke modul aslinya. Hal ini menyebabkan loop rekursif. Plugin terus mengekstrak interface bersarang hingga menghasilkan 630 tipe. Dokumentasinya penuh dengan noise. Hal ini merusak pengalaman pengguna.

Solusinya: Early Garbage Collection

Saya membutuhkan tipe-tipe tersebut berada di modul yang benar tanpa noise tambahan. Saya berhenti mencoba memperbaiki output dan mulai memperbaiki prosesnya.

Saya menggunakan hook bernama EVENT_RESOLVE_END. Ini memungkinkan saya mencegat AST tepat setelah resolusi. Saya melakukan ini sebelum TypeDoc menetapkan kategori atau menggunakan memori yang besar.

Logika saya mengikuti tiga langkah:

Hasilnya: Saya menyelamatkan 240 tipe vital. Tipe-tipe tersebut kini terlihat dan diarahkan dengan benar. Saya berhasil menghindari noise rekursif dari eksperimen ketiga.

Pelajaran yang Dipetik

• Tangani AST lebih awal. Menghapus node yang tidak diperlukan mencegah pemborosan memori nantinya. • Gunakan hook, bukan hack. Memahami siklus hidup compiler memungkinkan pengerjaan yang bersih. • Umpan balik meningkatkan arsitektur. Tinjauan dari maintainer membantu saya membangun sistem yang lebih baik. • Lebih banyak data tidak selalu lebih baik. Rekayasa yang baik berarti menemukan keseimbangan antara data dan usability.

Melampaui Ekspor yang Hilang: Membangun Garbage Collector Dini untuk TypeDoc AST Webpack

Pernahkah Anda menyadari bagaimana TypeDoc terkadang menyertakan dokumentasi untuk hal-hal yang bahkan tidak Anda maksudkan untuk diekspor? Hal ini dapat menyebabkan dokumentasi yang membengkak dan membingungkan pengguna. Masalah ini sering kali berakar pada bagaimana AST (Abstract Syntax Tree) dikonstruksi dan dikelola selama proses pembuatan dokumentasi.

Dalam artikel ini, kita akan mengeksplorasi konsep membangun sebuah garbage collector dini yang bekerja langsung pada AST TypeDoc untuk memangkas node yang tidak terjangkau (unreachable nodes), memastikan bahwa hanya kode yang benar-benar diekspor dan digunakan yang muncul dalam dokumentasi akhir.

Masalah: Dokumentasi yang Terlalu Inklusif

Secara default, TypeDoc mencoba untuk memetakan sebanyak mungkin simbol yang tersedia dalam modul Anda. Meskipun ini berguna untuk cakupan yang menyeluruh, dalam proyek skala besar, hal ini sering kali menyebabkan "kebisingan" dokumentasi. Simbol-simbol internal, fungsi pembantu (helper functions), atau variabel yang hanya digunakan secara internal tetapi secara tidak sengaja terdeteksi sebagai bagian dari modul dapat muncul di dokumentasi publik.

Masalah ini menjadi lebih rumit ketika kita bekerja dengan bundler seperti Webpack, di mana batas antara apa yang "dieksport" dan apa yang "digunakan" bisa menjadi kabur karena proses tree-shaking.

Solusi: Garbage Collection pada AST

Ide dasarnya adalah menerapkan algoritma Garbage Collection (GC) sederhana pada AST sebelum dokumentasi akhir dihasilkan. Alih-alih mencoba menentukan apa yang tidak boleh disertakan, kita akan menentukan apa yang harus disertakan berdasarkan titik masuk (entry points) yang ditentukan.

Kita dapat menggunakan pendekatan Mark-and-Sweep:

  1. Mark (Tandai): Mulai dari titik masuk yang ditentukan (misalnya, file index.ts atau daftar ekspor utama). Telusuri seluruh AST dan tandai semua simbol, tipe, dan node yang dapat dijangkau dari titik-titik tersebut.
  2. Sweep (Sapu): Telusuri kembali AST dan hapus semua node yang tidak ditandai sebagai "terjangkau".

Implementasi Langkah demi Langkah

1. Mengidentifikasi Titik Masuk

Langkah pertama adalah menentukan apa yang dianggap sebagai "akar" (root) dari dokumentasi kita. Dalam konteks TypeDoc, ini biasanya adalah daftar ekspor yang didefinisikan secara eksplisit dalam file entry point Anda.

2. Fase Penandaan (Marking Phase)

Kita perlu melakukan traversal pada AST. Saat kita menemukan sebuah simbol yang diekspor, kita menandainya sebagai reachable. Kemudian, kita harus menelusuri dependensi dari simbol tersebut. Jika sebuah fungsi diekspor, maka tipe data yang digunakan dalam parameter atau nilai kembalian fungsi tersebut juga harus ditandai sebagai reachable.

// Contoh logika pseudo-code untuk penandaan
function markReachable(node: ASTNode, visited: Set<ASTNode>) {
  if (visited.has(node)) return;
  visited.add(node);

  for (const child of node.children) {
    if (isExported(child) || isDependency(child)) {
      markReachable(child, visited);
    }
  }
}

3. Fase Penyapuan (Sweeping Phase)

Setelah fase penandaan selesai, kita memiliki set berisi semua node yang valid. Kita kemudian melakukan iterasi pada AST utama dan menghapus node yang tidak ada dalam set visited.

// Contoh logika pseudo-code untuk penyapuan
function sweepUnreachable(root: ASTNode, visited: Set<ASTNode>) {
  root.children = root.children.filter(child => visited.has(child));
  for (const child of root.children) {
    sweepUnreachable(child, visited);
  }
}

Tantangan dan Pertimbangan

Membangun garbage collector untuk AST tidaklah tanpa hambatan. Beberapa tantangan utama meliputi:

Kesimpulan

Dengan mengimplementasikan garbage collector dini pada AST TypeDoc, kita dapat menghasilkan dokumentasi yang lebih bersih, lebih ringkas, dan lebih relevan bagi pengguna. Meskipun implementasinya memerlukan ketelitian dalam menangani kompleksitas AST, manfaatnya dalam mengurangi kebisingan dokumentasi pada proyek besar sangatlah besar.

Pendekatan ini mengubah cara kita memandang dokumentasi: bukan sekadar refleksi dari seluruh kode sumber, melainkan representasi yang dikurasi secara cermat dari API publik kita.