𝗕𝗲𝘆𝗼𝗻𝗱 𝗠𝗶𝘀𝘀𝗶𝗻𝗴 𝗘𝘅𝗽𝗼𝗿𝘁𝘀: 𝗕𝘂𝗶𝗹𝗱𝗶𝗻𝗴 𝗮𝗻 𝗘𝗮𝗿𝗹𝘆 𝗚𝗮𝗿𝗯𝗮𝗴𝗲 𝗖𝗼𝗹𝗹𝗲𝗰𝘁𝗼𝗿
I tried to use a standard plugin to fix missing links in Webpack documentation. It failed.
Integrating a plugin into a large codebase is not a simple task. It became an architectural challenge. I had to manage Abstract Syntax Tree (AST) manipulation, memory use, and recursive loops.
The Problem with Standard Plugins
I ran three experiments to find a solution.
Experiment 1: The plugin recovered 135 types. However, it put them in an internal module. Our tool created a separate folder for them. We had to sort them manually. The documentation was also structurally wrong.
Experiment 2: I turned on a setting to hide external types. This worked for some things. It reduced the payload to 60 Webpack types. But TypeDoc ignored nested dependencies. It left many types hidden while they still used memory.
Experiment 3: I tried to map types back to their original modules. This caused a recursive loop. The plugin kept extracting nested interfaces until it created 630 types. The documentation was full of noise. It ruined the user experience.
The Solution: Early Garbage Collection
I needed the types in their correct modules without the extra noise. I stopped trying to fix the output and started fixing the process.
I used a hook called EVENT_RESOLVE_END. This let me intercept the AST right after resolution. I did this before TypeDoc assigned categories or used heavy memory.
My logic followed three steps:
- Find the internal module in the AST.
- Check every node using a custom utility.
- Delete the noise. I used project.removeReflection to delete 300 unneeded nodes immediately. This let Node.js free the memory.
- Move the important types. I merged the remaining 300 types into the root scope.
The result: I saved 240 vital types. They are now visible and correctly routed. I avoided the recursive noise of the third experiment.
Lessons Learned
• Handle ASTs early. Removing unneeded nodes prevents memory waste later. • Use hooks instead of hacks. Understanding the compiler lifecycle allows for clean work. • Feedback improves architecture. Maintainer reviews helped me build a better system. • More data is not better. Good engineering means finding the balance between data and usability.
Eksik Export'ların Ötesinde: Webpack'in TypeDoc AST'si İçin Erken Aşama Bir Garbage Collector Oluşturmak
TypeDoc, TypeScript projeleri için dokümantasyon oluşturmanın standart yoludur. Ancak, büyük ölçekli projelerde TypeDoc'un oluşturduğu AST (Abstract Syntax Tree - Soyut Sözdizimi Ağacı), bazen gereksiz yere şişebilir. Bu şişkinliğin temel nedeni, aslında dışarıya açılmayan (unexported) ancak AST içinde yer alan sembollerdir.
Bu yazıda, bu sorunu çözmek için Webpack'in TypeDoc AST'si üzerinde çalışan erken aşama bir "Garbage Collector" (Çöp Toplayıcı) mekanizmasının nasıl inşa edileceğini inceleyeceğiz.
Sorun: Şişkin AST ve Eksik Export'lar
TypeDoc, kodunuzu analiz ederken her bir sembol (sınıf, fonksiyon, değişken vb.) için bir düğüm (node) oluşturur. İdeal bir durumda, sadece export edilen sembollerin ve bunlara bağlı olanların dokümantasyonda yer almasını bekleriz.
Ancak, karmaşık bağımlılık ağaçlarında TypeDoc, bazen sadece içsel (internal) kullanım için olan veya aslında hiçbir şekilde erişilemeyen sembolleri de AST'ye dahil eder. Bu durum iki ana soruna yol açar:
- Bellek Kullanımı: AST'nin boyutu gereksiz yere artar.
- Performans: AST üzerinde yapılan sonraki işlemler (dokümantasyon üretimi, analiz vb.) daha uzun sürer.
"Eksik export" (missing exports) kavramı genellikle dokümantasyonda görünmesi gereken bir şeyin görünmemesi durumunu ifade eder. Bizim odaklandığımız nokta ise tam tersi: Görünmemesi gereken şeylerin AST'de yer kaplaması.
Çözüm: Erken Aşama Bir Garbage Collector
Bu sorunu aşmak için, AST oluşturma sürecinin erken bir aşamasında devreye giren bir "Garbage Collector" mekanizması tasarlayabiliriz. Bu mekanizmanın temel mantığı şudur:
- Erişilebilirlik Analizi: Tüm
exportedilen kök düğümleri belirle. - İşaretleme (Marking): Bu kök düğümlerden başlayarak, tüm bağlı (reachable) düğümleri işaretle.
- Temizleme (Sweeping): İşaretlenmemiş tüm düğümleri AST'den kaldır.
Bu, klasik "Mark-and-Sweep" algoritmasının AST yapısına uyarlanmış bir versiyonudur.
Uygulama
Aşağıda, bu mantığı nasıl uygulayabileceğimize dair basitleştirilmiş bir yaklaşım yer almaktadır.
// Basitleştirilmiş bir örnek
function garbageCollect(ast: TypeDocAST) {
const reachableNodes = new Set<Node>();
// 1. Adım: Kök düğümleri (export edilenleri) bul ve işaretle
const roots = ast.getExportedSymbols();
for (const root of roots) {
markReachable(root, reachableNodes);
}
// 2. Adım: İşaretlenmemiş düğümleri temizle
ast.nodes.filter(node => !reachableNodes.has(node));
}
function markReachable(node: Node, visited: Set<Node>) {
if (visited.has(node)) return;
visited.add(node);
for (const child of node.children) {
markReachable(child, visited);
}
}
Sonuç
AST üzerinde çalışan bir Garbage Collector uygulamak, özellikle büyük ölçekli TypeScript projelerinde TypeDoc'un performansını ve verimliliğini önemli ölçüde artırabilir. Bu yaklaşım, sadece "eksik export" sorununu çözmekle kalmaz, aynı zamanda dokümantasyon oluşturma sürecini daha öngörülebilir hale getirir.