https://github.com/canadianeagle/vite-plugin-component-debugger
A Vite plugin that adds data attributes to JSX/TSX elements for development tracking and debugging
https://github.com/canadianeagle/vite-plugin-component-debugger
ai ast-transformation babel-parser component-debugger component-tracking debugging development-tools devtools hmr hot-reload jsx lovable react tagger tsx typescript vibe-coding vite vite-plugin
Last synced: 16 days ago
JSON representation
A Vite plugin that adds data attributes to JSX/TSX elements for development tracking and debugging
- Host: GitHub
- URL: https://github.com/canadianeagle/vite-plugin-component-debugger
- Owner: canadianeagle
- License: mit
- Created: 2025-09-19T00:53:31.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2025-09-28T04:58:30.000Z (24 days ago)
- Last Synced: 2025-09-28T06:22:32.471Z (24 days ago)
- Topics: ai, ast-transformation, babel-parser, component-debugger, component-tracking, debugging, development-tools, devtools, hmr, hot-reload, jsx, lovable, react, tagger, tsx, typescript, vibe-coding, vite, vite-plugin
- Language: TypeScript
- Homepage: https://www.tonyebrown.com/apps/vite-plugin-component-debugger
- Size: 257 KB
- Stars: 3
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- Changelog: changelog.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# vite-plugin-component-debugger

[](https://badge.fury.io/js/vite-plugin-component-debugger)
[](https://www.npmjs.com/package/vite-plugin-component-debugger)
[](https://github.com/canadianeagle/vite-plugin-component-debugger/blob/main/LICENSE)
[](https://github.com/canadianeagle/vite-plugin-component-debugger)[](https://github.com/canadianeagle/vite-plugin-component-debugger/actions)
[](https://github.com/canadianeagle/vite-plugin-component-debugger/actions)
[](http://www.typescriptlang.org/)
[](https://vitejs.dev/)[](https://www.buymeacoffee.com/tonyebrown)
[](https://twitter.com/truevined)A **highly customizable** Vite plugin that automatically adds data attributes to JSX/TSX elements during development. Track, debug, and understand component rendering with powerful features like path filtering, attribute transformers, presets, and more. **Perfect for AI-generated code** and debugging "which component rendered this?" π€
## β¨ What's New in v2.2
**Performance Optimizations (v2.2.0):**
- π **15-30% faster** build times with 3 micro-optimizations
- β‘ **5-10x faster path matching** with pre-compiled glob patterns
- π¦ **2-3x faster metadata encoding** with optimized JSON serialization
- π§ **Modular architecture** - Clean, maintainable 7-file structure**V2 Features - Complete control over component debugging:**
- π― **Path Filtering** - Include/exclude files with glob patterns
- π§ **Attribute Transformers** - Customize any attribute value (privacy, formatting)
- π¨ **Presets** - Quick configs for common use cases (minimal, testing, debugging, production)
- β‘ **Conditional Tagging** - Tag only specific components with `shouldTag` callback
- π·οΈ **Custom Attributes** - Add your own data attributes (git info, environment, etc.)
- π¦ **Metadata Encoding** - Choose JSON, Base64, or plain text encoding
- π **Statistics & Callbacks** - Track processing stats and export metrics
- ποΈ **Depth Filtering** - Control tagging by component nesting level
- π **Attribute Grouping** - Combine all attributes into single JSON attribute
- πΊοΈ **Source Map Hints** - Better debugging with source map comments**π [View Detailed Examples & Use Cases](./EXAMPLES.md)**
## Quick Start
```bash
# Install
pnpm add -D vite-plugin-component-debugger
# or: npm install --save-dev vite-plugin-component-debugger
# or: yarn add -D vite-plugin-component-debugger
``````typescript
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import componentDebugger from "vite-plugin-component-debugger";export default defineConfig({
plugins: [
componentDebugger(), // β οΈ IMPORTANT: Must be BEFORE react()
react(),
],
});
```> **β οΈ CRITICAL**: componentDebugger() must be placed **BEFORE** react() plugin, otherwise line numbers will be wrong
## What It Does
**Before:**
```jsx
// src/components/Button.tsx (line 10)Click me
```
**After (Default - All Attributes):**
```jsx
Click me
```
**After (Minimal Preset - Clean):**
```jsx
componentDebugger({ preset: 'minimal' })// Results in:
Click me
```
**After (Custom Filtering):**
```jsx
componentDebugger({
includeAttributes: ["id", "name", "line"]
})// Results in:
Click me
```
## Key Benefits
- π **Debug Faster**: Find which component renders any DOM element
- π **Jump to Source**: Go directly from DevTools to your code
- π― **Stable Testing**: Use data attributes for reliable E2E tests
- β‘ **Zero Runtime Cost**: Only runs during development
- π§ **Smart Exclusions**: Automatically skips Fragment and Three.js elements## Configuration
### Basic Configuration
```typescript
componentDebugger({
enabled: process.env.NODE_ENV === "development", // When to run
attributePrefix: "data-dev", // Custom prefix
extensions: [".jsx", ".tsx"], // File types
});
```### Quick Start with Presets
```typescript
// Minimal - only ID attribute (cleanest DOM)
componentDebugger({ preset: "minimal" });// Testing - ID, name, component (perfect for E2E)
componentDebugger({ preset: "testing" });// Debugging - everything + metadata (full visibility)
componentDebugger({ preset: "debugging" });// Production - privacy-focused with shortened paths
componentDebugger({ preset: "production" });
```**[π See all preset details in EXAMPLES.md](./EXAMPLES.md#presets)**
### Common Configurations
π― Clean DOM - Minimal Attributes
```typescript
componentDebugger({
includeAttributes: ["id", "name"], // Only these attributes
});
// Result: Only data-dev-id and data-dev-name
```**[See more attribute filtering examples β](./EXAMPLES.md#attribute-filtering)**
ποΈ Path Filtering - Specific Directories
```typescript
componentDebugger({
includePaths: ["src/components/**", "src/features/**"],
excludePaths: ["**/*.test.tsx", "**/*.stories.tsx"],
});
```**[See path filtering patterns β](./EXAMPLES.md#path-filtering)**
π§ Privacy - Transform Paths
```typescript
componentDebugger({
transformers: {
path: (p) => p.split("/").slice(-2).join("/"), // Shorten paths
id: (id) => id.split(":").slice(-2).join(":"), // Remove path from ID
},
});
```**[See transformer examples β](./EXAMPLES.md#attribute-transformers)**
β‘ Conditional - Tag Specific Components
```typescript
componentDebugger({
shouldTag: ({ elementName }) => {
// Only tag custom components (uppercase)
return elementName[0] === elementName[0].toUpperCase();
},
});
```**[See conditional tagging patterns β](./EXAMPLES.md#conditional-tagging)**
> **π‘ Pro Tip:** Use `includeAttributes` for cleaner DOM instead of legacy `includeProps`/`includeContent`
> **β οΈ Gotcha:** When both `includeAttributes` and `excludeAttributes` are set, `includeAttributes` takes priority
### Configuration Reference
Core Options
| Option | Type | Default | Description |
| ----------------- | ---------- | ------------------ | --------------------------------------------------------------------------- |
| `enabled` | `boolean` | `true` | Enable/disable the plugin |
| `attributePrefix` | `string` | `'data-dev'` | Prefix for data attributes |
| `extensions` | `string[]` | `['.jsx', '.tsx']` | File extensions to process |
| `preset` | `Preset` | `undefined` | Quick config: `'minimal'` \| `'testing'` \| `'debugging'` \| `'production'` |V2 Features - Attribute Control
| Option | Type | Default | Description |
| ------------------- | ----------------- | ----------- | ------------------------------------------------ |
| `includeAttributes` | `AttributeName[]` | `undefined` | **Recommended:** Only include these attributes |
| `excludeAttributes` | `AttributeName[]` | `undefined` | Exclude these attributes |
| `transformers` | `object` | `undefined` | Transform attribute values (privacy, formatting) |
| `groupAttributes` | `boolean` | `false` | Combine all into single JSON attribute |**Available:** `'id'`, `'name'`, `'path'`, `'line'`, `'file'`, `'component'`, `'metadata'`
**[β Full attribute control examples](./EXAMPLES.md#attribute-filtering)**
V2 Features - Path & Element Filtering
| Option | Type | Default | Description |
| ----------------- | ------------- | -------------------------------- | ------------------------ |
| `includePaths` | `string[]` | `undefined` | Glob patterns to include |
| `excludePaths` | `string[]` | `undefined` | Glob patterns to exclude |
| `excludeElements` | `string[]` | `['Fragment', 'React.Fragment']` | Element names to skip |
| `customExcludes` | `Set` | Three.js elements | Custom elements to skip |**[β Path filtering patterns](./EXAMPLES.md#path-filtering)**
V2 Features - Conditional & Custom
| Option | Type | Default | Description |
| ------------------ | ---------------------------------- | ----------- | -------------------------------------------- |
| `shouldTag` | `(info) => boolean` | `undefined` | Conditionally tag components |
| `customAttributes` | `(info) => Record` | `undefined` | Add custom attributes dynamically |
| `metadataEncoding` | `MetadataEncoding` | `'json'` | Encoding: `'json'` \| `'base64'` \| `'none'` |**[β Conditional tagging](./EXAMPLES.md#conditional-tagging)** β’ **[β Custom attributes](./EXAMPLES.md#custom-attributes)**
V2 Features - Depth, Stats & Advanced
| Option | Type | Default | Description |
| ----------------------- | ----------------- | ----------- | ----------------------- |
| `maxDepth` | `number` | `undefined` | Maximum nesting depth |
| `minDepth` | `number` | `undefined` | Minimum nesting depth |
| `tagOnlyRoots` | `boolean` | `false` | Only tag root elements |
| `onTransform` | `(stats) => void` | `undefined` | Per-file callback |
| `onComplete` | `(stats) => void` | `undefined` | Completion callback |
| `exportStats` | `string` | `undefined` | Export stats to file |
| `includeSourceMapHints` | `boolean` | `false` | Add source map comments |
| `debug` | `boolean` | `false` | Enable debug logging |**[β Depth filtering](./EXAMPLES.md#depth-filtering)** β’ **[β Statistics](./EXAMPLES.md#statistics--callbacks)**
> **π‘ All v2 features are opt-in** - Existing configs work unchanged
>
> **π See complete TypeScript types:** `import { type TagOptions } from 'vite-plugin-component-debugger'`**π [View 50+ Detailed Examples in EXAMPLES.md β](./EXAMPLES.md)**
Examples include: E2E testing setups, debug overlays, monorepo configs, feature flags, performance monitoring, and more!
## Use Cases
### 1. Development Debugging (Simple)
Find components in the DOM:
```javascript
// In browser console
document.querySelectorAll('[data-dev-component="Button"]');
console.log("Button locations:", [...$$('[data-dev-path*="Button"]')]);
```### 2. E2E Testing (Intermediate)
Stable selectors for tests:
```javascript
// Cypress
cy.get('[data-dev-component="SubmitButton"]').click();
cy.get('[data-dev-path*="LoginForm"]').should("be.visible");// Playwright
await page.click('[data-dev-component="SubmitButton"]');
await expect(page.locator('[data-dev-path*="LoginForm"]')).toBeVisible();
```### 3. Visual Debugging Tools (Advanced)
Build custom debugging overlays:
```javascript
// Show component boundaries on hover
document.addEventListener("mouseover", (e) => {
const target = e.target;
if (target.dataset?.devComponent) {
target.style.outline = "2px solid red";
console.log(`Component: ${target.dataset.devComponent}`);
console.log(`Location: ${target.dataset.devPath}:${target.dataset.devLine}`);
}
});
```### 4. Performance Monitoring (Expert)
Track component render activity:
```javascript
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === "childList") {
mutation.addedNodes.forEach((node) => {
if (node.dataset?.devId) {
console.log(`Component rendered: ${node.dataset.devId}`);
}
});
}
});
});observer.observe(document.body, { childList: true, subtree: true });
```## Advanced Features
### Environment-Specific Setup
```typescript
// Different configs per environment
const isDev = process.env.NODE_ENV === "development";
const isStaging = process.env.NODE_ENV === "staging";export default defineConfig({
plugins: [
componentDebugger({
enabled: isDev || isStaging,
attributePrefix: isStaging ? "data-staging" : "data-dev",
includeProps: isDev, // Enable metadata in development
includeContent: isDev, // Enable content capture in development
}),
react(),
],
});
```### React Three Fiber Support
Automatically excludes Three.js elements:
```typescript
// Default exclusions
componentDebugger({
customExcludes: new Set([
"mesh",
"group",
"scene",
"camera",
"ambientLight",
"directionalLight",
"pointLight",
"boxGeometry",
"sphereGeometry",
"planeGeometry",
"meshBasicMaterial",
"meshStandardMaterial",
// ... and many more
]),
});// To include Three.js elements
componentDebugger({
customExcludes: new Set(), // Empty set = tag everything
});
```### TypeScript Support
Full type definitions included:
```typescript
import componentDebugger, { type TagOptions } from "vite-plugin-component-debugger";const config: TagOptions = {
enabled: true,
attributePrefix: "data-track",
};export default defineConfig({
plugins: [componentDebugger(config), react()],
});
```### Build Performance & Statistics
```
π Component Debugger Statistics:
Total files scanned: 45
Files processed: 32
Elements tagged: 287
```**Performance optimizations (v2.2.0):**
- π **15-30% faster** than v2.1 with 3 micro-optimizations
- β‘ **Pre-compiled glob patterns** - 5-10x faster path matching
- π¦ **Optimized JSON serialization** - 2-3x faster metadata encoding
- π§ **Smart string operations** - 2x faster debug logging
- **Time savings**: 200-500ms on 100-file projects, 2-5s on 1000-file projects
- Efficient AST traversal with caching
- Minimal HMR impact
- Automatically skips `node_modules`
- Only runs during development### Troubleshooting & Common Gotchas
β οΈ Line numbers are wrong/offset by ~19? (Most common issue)
**Problem:** `data-dev-line` shows numbers ~19 higher than expected
**Cause:** Plugin order is wrong - React plugin adds ~19 lines of imports/HMR setup
**Fix:** Move `componentDebugger()` BEFORE `react()` in Vite config
```typescript
// β WRONG - Line numbers will be offset
export default defineConfig({
plugins: [
react(), // Transforms code first, adds ~19 lines
componentDebugger(), // Gets wrong line numbers
],
});// β CORRECT - Accurate line numbers
export default defineConfig({
plugins: [
componentDebugger(), // Processes original source first
react(), // Transforms after tagging
],
});
```Elements not being tagged?
1. **Check file extension:** File must match `extensions` (default: `.jsx`, `.tsx`)
2. **Check exclusions:** Element not in `excludeElements` or `customExcludes`
3. **Check paths:** File not excluded by `excludePaths` pattern
4. **Check plugin order:** `componentDebugger()` before `react()`
5. **Check enabled:** Plugin is enabled (`enabled: true`)
6. **Check shouldTag:** If using `shouldTag`, callback must return `true`**Debug with:**
```typescript
componentDebugger({
debug: true, // Shows what's being processed
enabled: true,
});
```Build performance issues?
**Quick fixes:**
1. Use `includeAttributes` to reduce DOM size:
```typescript
includeAttributes: ["id", "name"]; // Only essential attributes
```
2. Filter paths to only process needed directories:
```typescript
includePaths: ['src/components/**'],
excludePaths: ['**/*.test.tsx', '**/*.stories.tsx']
```
3. Use `maxDepth` to limit deep nesting:
```typescript
maxDepth: 5; // Only tag up to 5 levels deep
```
4. Skip test files with `excludePaths`**[β See performance optimization examples](./EXAMPLES.md#performance-monitoring)**
Attributes appearing in production?
```typescript
componentDebugger({
enabled: process.env.NODE_ENV !== "production",
});
```Or use environment-specific configs:
```typescript
enabled: isDev || isStaging, // Not in production
```includeAttributes vs excludeAttributes priority?
**Gotcha:** When both are set, `includeAttributes` takes priority
```typescript
componentDebugger({
includeAttributes: ["id", "name", "line"],
excludeAttributes: ["name"], // β οΈ This is IGNORED
});
// Result: Only id, name, line are included
```**Best practice:** Use one or the other, not both
TypeScript type errors?
Import types for full IntelliSense:
```typescript
import componentDebugger, {
type TagOptions,
type ComponentInfo,
type AttributeName,
} from "vite-plugin-component-debugger";const config: TagOptions = {
// Full type checking
};
```## Development & Contributing
### Auto-Release Workflow
π **Every commit to `main` triggers automatic release:**
**Commit Message β Version Bump:**
- `BREAKING CHANGE:` or `major:` β Major (1.0.0 β 2.0.0)
- `feat:` or `feature:` or `minor:` β Minor (1.0.0 β 1.1.0)
- Everything else β Patch (1.0.0 β 1.0.1)**Example commit messages:**
```bash
# Major version (breaking changes)
git commit -m "BREAKING CHANGE: removed deprecated API"
git commit -m "major: complete rewrite of plugin interface"# Minor version (new features)
git commit -m "feat: add TypeScript 5.0 support"
git commit -m "feature: new configuration option for props"
git commit -m "minor: add custom exclude patterns"# Patch version (bug fixes, docs, chores)
git commit -m "fix: resolve memory leak in transformer"
git commit -m "docs: update README examples"
git commit -m "chore: update dependencies"# Skip release
git commit -m "docs: fix typo [skip ci]"
```**What happens automatically:**
1. Tests run, package builds
2. Version bump based on commit message
3. GitHub release created with changelog
4. Package published to npm**Setup auto-publishing:**
1. Get NPM token: `npm token create --type=automation`
2. Add to GitHub repo: **Settings** β **Secrets** β `NPM_TOKEN`
3. Commit to `main` branch to trigger first release### Contributing
1. Fork and clone
2. `pnpm install`
3. Make changes and add tests
4. `pnpm run check` (lint + test + build)
5. Commit with semantic message (see above)
6. Open PRSee [`.github/COMMIT_CONVENTION.md`](.github/COMMIT_CONVENTION.md) for examples.
### Development Setup
```bash
git clone https://github.com/yourusername/vite-plugin-component-debugger.git
cd vite-plugin-component-debugger
pnpm install
pnpm run test # Run tests
pnpm run build # Build package
pnpm run check # Full validation
```## Author & Support
**Tonye Brown** - Builder, Front-end developer, designer, and performance optimization expert crafting immersive web experiences. Also a Music Producer and Artist.
**Connect:**
- π [Website](https://www.tonyebrown.com)
- π [Plugin Docs](https://www.tonyebrown.com/apps/vite-plugin-component-debugger)
- π¦ [Twitter](https://www.twitter.com/truevined)
- πΌ [LinkedIn](https://www.linkedin.com/in/tonyeb/)**Support This Project:**
- β Star this repository
- β [Buy me a coffee](https://www.buymeacoffee.com/tonyebrown)
- π [Sponsor on GitHub](https://github.com/sponsors/canadianeagle)
- π Report issues or suggest features
- π€ Contribute code via pull requests
- π’ Share with other developers## License
MIT Β© [Tonye Brown](https://www.tonyebrown.com)
---
**Made with β€οΈ by [Tonye Brown](https://www.tonyebrown.com)**
_Inspired by [lovable-tagger](https://www.npmjs.com/package/lovable-tagger), enhanced for the Vite ecosystem._
[](https://github.com/canadianeagle)
[](https://www.tonyebrown.com)
[](https://www.linkedin.com/in/tonyeb/)**β Star this repo if it helped you!**