Part 4 of building Additional Context Menus - where I share the war stories, 3 AM debugging sessions, and breakthrough moments that almost made me quit (but didn't). Every developer needs to hear these stories.
TL;DR π―
Building this VS Code extension was 10% inspiration and 90% debugging edge cases I never imagined existed. From a 601KB bundle that made users cry, to writing 37 tests to catch bugs that only happened at 3 AM, to the philosophical crisis of AST vs Regex parsing. But hey - the breakthroughs made it all worth it! β‘
The Bundle Size Horror Story That Haunted My Dreams π
The Moment Everything Went Wrong
Picture this: I'm finally ready to ship v1.0. I run npm run build
and see:
β
Build complete: 601KB bundle
601KB. For a context menu extension. π±
That's larger than some entire websites! VS Code guidelines recommend extensions stay under 50KB. I had built a monster that would take forever to download, consume ridiculous memory, and make VS Code feel sluggish.
I literally stared at my screen for 10 minutes in disbelief.
The Great Bundle Investigation
I dove into bundle analysis and found the culprits:
- Babel ecosystem: 400KB+ of AST parsing libraries
- Webpack overhead: 150KB+ of bundling infrastructure
- Unused dependencies: 50KB+ of "just in case" packages
The extension was supposed to make developers more productive. Instead, it was digital bloatware. π€¦ββοΈ
The esbuild Salvation
After a weekend of ripping out webpack and rebuilding with esbuild:
Before: 601KB bundle in 19 seconds π΄
After: 24.75KB bundle in 0.8 seconds β‘
Improvement: 95.9% smaller, 20x faster
This single change transformed everything. Users went from "why is this so slow?" to "wow, this feels native!"
The Testing Nightmare That Consumed My Soul π§ͺ
When "It Works on My Machine" Wasn't Enough
I started with 19 basic tests. They all passed. I was confident. Then users started reporting bizarre edge cases:
- Extension crashes on files with emoji in function names π
- Import merging fails with 1000+ line files
- Context menus disappear randomly in workspaces
- Copy function breaks on deeply nested code (20+ levels)
Each bug report felt like a personal attack on my competence as a developer.
The Edge Case Rabbit Hole
I spent two weeks writing 18 additional tests for edge cases I never imagined:
// Who writes code like this? Apparently, everyone.
const πrocket = () => {
const nested = () => {
const deeper = () => {
const evenDeeper = /* 15 more levels */ "chaos";
};
};
};
My favorite test case: "Should handle functions with special characters in paths on Windows systems with spaces in folder names during concurrent save operations while the user is typing."
Yes, that's a real test. Yes, it was failing.
The Breakthrough Moment
After hitting test #37, something clicked. I wasn't just fixing bugs - I was building bulletproof reliability. Each edge case made the extension stronger.
Final score: 37/37 tests passing β
Users stopped reporting crashes. The extension became rock solid. Worth every 3 AM debugging session!
The Great Philosophy War: AST vs Regex π₯
The "Proper" Way That Nearly Killed Me
"You MUST use Abstract Syntax Trees for parsing! Regex is for amateurs!" - Every computer science professor ever
I built this beautiful, academically perfect AST parser with Babel:
// The "right" way (that added 400KB to the bundle)
import { parse } from '@babel/parser';
import traverse from '@babel/traverse';
const ast = parse(code, {
sourceType: 'module',
plugins: ['typescript', 'jsx', 'decorators', 'classProperties']
});
It was elegant. It handled every edge case. It was also massive, slow, and overkill for finding function boundaries.
The Heretical Regex Solution
At 2 AM, exhausted and frustrated, I had a forbidden thought:
"What if I just... used regex?" π
// The "wrong" way that actually works perfectly
const functionPattern = /^(\s*)(?:export\s+)?(async\s+)?function\s+(\w+)/gm;
The results were shocking:
- β 400KB+ bundle savings
- β 10x faster execution
- β 95% accuracy (perfect for real-world code)
- β Zero dependency bloat
Sometimes the "wrong" solution is exactly right. π―
The User Feedback Plot Twist That Changed Everything π
The Comment That Broke My Assumptions
I was obsessing over advanced features when this comment appeared:
"Love the extension! But honestly, I just want 'Save All' to work reliably. The fancy stuff is nice, but I need the basics to be bulletproof." - Sarah, React Developer
Mind. Blown. π€―
I was building a Ferrari when users needed a reliable Honda Civic.
The Priority Shift
This comment triggered a complete strategy change:
- Before: Add more features, impress with complexity
- After: Perfect the core features, focus on reliability
I spent the next month:
- Making Save All handle edge cases gracefully
- Adding progress feedback for long operations
- Improving error messages and recovery
- Testing on massive codebases
Result: Users started saying it "feels like VS Code should have shipped with this built-in."
That's when you know you nailed it. β¨
The Victory Moments That Made It All Worth It π
When Performance Optimization Clicked
Watching build times drop from 19 seconds to under 1 second felt like discovering fire. The development experience transformation was unreal - I could iterate 20x faster!
When the Tests Finally All Passed
After weeks of red test failures, seeing that green "37/37 passing" was pure euphoria. Every edge case conquered, every crash eliminated.
When Users Started Saying "Magic"
The first time someone commented "This extension reads my mind" - that's the moment all the 3 AM debugging sessions felt worth it.
The Lessons That Stick With You π§
Performance matters more than features. Users forgive missing features. They don't forgive slow, unreliable software.
Edge cases are everywhere. That weird edge case you think no one will hit? Someone's hitting it right now.
User feedback trumps personal assumptions. Listen to what users actually need, not what you think they should want.
Simple solutions often beat complex ones. Sometimes regex IS better than AST parsing. Fight me. π
Persistence beats perfection. Those 3 AM debugging sessions taught me more than any tutorial ever could.
What's Coming Next π
In Part 5, I'll share the advice I'd give my past self (and you!) about building developer tools that don't suck. Plus, a sneak peek at the exciting features planned for v2.0!
The journey was brutal, educational, and ultimately rewarding. Every crashed build, every failed test, every confused user report made the extension better.
Try it yourself! Install Additional Context Menus and see these hard-won improvements in action.
Coming up next: Part 5 - What I'd Tell My Past Self About Building Extensions That Actually Help Developers π―
What's your worst debugging story? Drop it in the comments - I need to feel better about my 6-hour semicolon hunt! π
Top comments (0)