{"id":31588535,"url":"https://github.com/canadianeagle/vite-plugin-component-debugger","last_synced_at":"2025-10-06T02:11:30.652Z","repository":{"id":315534731,"uuid":"1059796905","full_name":"canadianeagle/vite-plugin-component-debugger","owner":"canadianeagle","description":"A Vite plugin that adds data attributes to JSX/TSX elements for development tracking and debugging","archived":false,"fork":false,"pushed_at":"2025-09-28T04:58:30.000Z","size":263,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-28T06:22:32.471Z","etag":null,"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"],"latest_commit_sha":null,"homepage":"https://www.tonyebrown.com/apps/vite-plugin-component-debugger","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/canadianeagle.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-19T00:53:31.000Z","updated_at":"2025-09-28T04:58:33.000Z","dependencies_parsed_at":"2025-09-19T07:43:28.529Z","dependency_job_id":null,"html_url":"https://github.com/canadianeagle/vite-plugin-component-debugger","commit_stats":null,"previous_names":["canadianeagle/vite-plugin-component-debugger"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/canadianeagle/vite-plugin-component-debugger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canadianeagle%2Fvite-plugin-component-debugger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canadianeagle%2Fvite-plugin-component-debugger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canadianeagle%2Fvite-plugin-component-debugger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canadianeagle%2Fvite-plugin-component-debugger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/canadianeagle","download_url":"https://codeload.github.com/canadianeagle/vite-plugin-component-debugger/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canadianeagle%2Fvite-plugin-component-debugger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278547821,"owners_count":26004775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["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"],"created_at":"2025-10-06T02:10:32.255Z","updated_at":"2025-10-06T02:11:30.646Z","avatar_url":"https://github.com/canadianeagle.png","language":"TypeScript","funding_links":["https://www.buymeacoffee.com/tonyebrown","https://github.com/sponsors/canadianeagle"],"categories":[],"sub_categories":[],"readme":"# vite-plugin-component-debugger\r\n\r\n\u003cdiv align=\"center\"\u003e\r\n\r\n![Vite Plugin Component Debugger](./assets/vite-plugin-component-debugger-image.jpeg)\r\n\r\n[![npm version](https://badge.fury.io/js/vite-plugin-component-debugger.svg)](https://badge.fury.io/js/vite-plugin-component-debugger)\r\n[![npm downloads](https://img.shields.io/npm/dm/vite-plugin-component-debugger.svg)](https://www.npmjs.com/package/vite-plugin-component-debugger)\r\n[![GitHub license](https://img.shields.io/github/license/canadianeagle/vite-plugin-component-debugger.svg)](https://github.com/canadianeagle/vite-plugin-component-debugger/blob/main/LICENSE)\r\n[![GitHub stars](https://img.shields.io/github/stars/canadianeagle/vite-plugin-component-debugger.svg?style=social\u0026label=Star)](https://github.com/canadianeagle/vite-plugin-component-debugger)\r\n\r\n[![Build Status](https://github.com/canadianeagle/vite-plugin-component-debugger/workflows/CI/badge.svg)](https://github.com/canadianeagle/vite-plugin-component-debugger/actions)\r\n[![Auto Release](https://github.com/canadianeagle/vite-plugin-component-debugger/workflows/Auto%20Release/badge.svg)](https://github.com/canadianeagle/vite-plugin-component-debugger/actions)\r\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)\r\n[![Vite](https://img.shields.io/badge/vite-%23646CFF.svg?style=flat\u0026logo=vite\u0026logoColor=white)](https://vitejs.dev/)\r\n\r\n[![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-ffdd00?style=flat\u0026logo=buy-me-a-coffee\u0026logoColor=black)](https://www.buymeacoffee.com/tonyebrown)\r\n[![Follow on Twitter](https://img.shields.io/twitter/follow/truevined?style=social)](https://twitter.com/truevined)\r\n\r\n\u003c/div\u003e\r\n\r\nA **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?\" 🤔\r\n\r\n## ✨ What's New in v2.2\r\n\r\n**Performance Optimizations (v2.2.0):**\r\n\r\n- 🚀 **15-30% faster** build times with 3 micro-optimizations\r\n- ⚡ **5-10x faster path matching** with pre-compiled glob patterns\r\n- 📦 **2-3x faster metadata encoding** with optimized JSON serialization\r\n- 🔧 **Modular architecture** - Clean, maintainable 7-file structure\r\n\r\n**V2 Features - Complete control over component debugging:**\r\n\r\n- 🎯 **Path Filtering** - Include/exclude files with glob patterns\r\n- 🔧 **Attribute Transformers** - Customize any attribute value (privacy, formatting)\r\n- 🎨 **Presets** - Quick configs for common use cases (minimal, testing, debugging, production)\r\n- ⚡ **Conditional Tagging** - Tag only specific components with `shouldTag` callback\r\n- 🏷️ **Custom Attributes** - Add your own data attributes (git info, environment, etc.)\r\n- 📦 **Metadata Encoding** - Choose JSON, Base64, or plain text encoding\r\n- 📊 **Statistics \u0026 Callbacks** - Track processing stats and export metrics\r\n- 🎚️ **Depth Filtering** - Control tagging by component nesting level\r\n- 🔐 **Attribute Grouping** - Combine all attributes into single JSON attribute\r\n- 🗺️ **Source Map Hints** - Better debugging with source map comments\r\n\r\n**📚 [View Detailed Examples \u0026 Use Cases](./EXAMPLES.md)**\r\n\r\n## Quick Start\r\n\r\n```bash\r\n# Install\r\npnpm add -D vite-plugin-component-debugger\r\n# or: npm install --save-dev vite-plugin-component-debugger\r\n# or: yarn add -D vite-plugin-component-debugger\r\n```\r\n\r\n```typescript\r\n// vite.config.ts\r\nimport { defineConfig } from \"vite\";\r\nimport react from \"@vitejs/plugin-react\";\r\nimport componentDebugger from \"vite-plugin-component-debugger\";\r\n\r\nexport default defineConfig({\r\n  plugins: [\r\n    componentDebugger(), // ⚠️ IMPORTANT: Must be BEFORE react()\r\n    react(),\r\n  ],\r\n});\r\n```\r\n\r\n\u003e **⚠️ CRITICAL**: componentDebugger() must be placed **BEFORE** react() plugin, otherwise line numbers will be wrong\r\n\r\n## What It Does\r\n\r\n**Before:**\r\n\r\n```jsx\r\n// src/components/Button.tsx (line 10)\r\n\u003cbutton className=\"btn-primary\" onClick={handleClick}\u003e\r\n  Click me\r\n\u003c/button\u003e\r\n```\r\n\r\n**After (Default - All Attributes):**\r\n\r\n```jsx\r\n\u003cbutton\r\n  data-dev-id=\"src/components/Button.tsx:10:2\"\r\n  data-dev-name=\"button\"\r\n  data-dev-path=\"src/components/Button.tsx\"\r\n  data-dev-line=\"10\"\r\n  data-dev-file=\"Button.tsx\"\r\n  data-dev-component=\"button\"\r\n  className=\"btn-primary\"\r\n  onClick={handleClick}\r\n\u003e\r\n  Click me\r\n\u003c/button\u003e\r\n```\r\n\r\n**After (Minimal Preset - Clean):**\r\n\r\n```jsx\r\ncomponentDebugger({ preset: 'minimal' })\r\n\r\n// Results in:\r\n\u003cbutton\r\n  data-dev-id=\"src/components/Button.tsx:10:2\"\r\n  className=\"btn-primary\"\r\n  onClick={handleClick}\r\n\u003e\r\n  Click me\r\n\u003c/button\u003e\r\n```\r\n\r\n**After (Custom Filtering):**\r\n\r\n```jsx\r\ncomponentDebugger({\r\n  includeAttributes: [\"id\", \"name\", \"line\"]\r\n})\r\n\r\n// Results in:\r\n\u003cbutton\r\n  data-dev-id=\"src/components/Button.tsx:10:2\"\r\n  data-dev-name=\"button\"\r\n  data-dev-line=\"10\"\r\n  className=\"btn-primary\"\r\n  onClick={handleClick}\r\n\u003e\r\n  Click me\r\n\u003c/button\u003e\r\n```\r\n\r\n## Key Benefits\r\n\r\n- 🐛 **Debug Faster**: Find which component renders any DOM element\r\n- 📍 **Jump to Source**: Go directly from DevTools to your code\r\n- 🎯 **Stable Testing**: Use data attributes for reliable E2E tests\r\n- ⚡ **Zero Runtime Cost**: Only runs during development\r\n- 🔧 **Smart Exclusions**: Automatically skips Fragment and Three.js elements\r\n\r\n## Configuration\r\n\r\n### Basic Configuration\r\n\r\n```typescript\r\ncomponentDebugger({\r\n  enabled: process.env.NODE_ENV === \"development\", // When to run\r\n  attributePrefix: \"data-dev\", // Custom prefix\r\n  extensions: [\".jsx\", \".tsx\"], // File types\r\n});\r\n```\r\n\r\n### Quick Start with Presets\r\n\r\n```typescript\r\n// Minimal - only ID attribute (cleanest DOM)\r\ncomponentDebugger({ preset: \"minimal\" });\r\n\r\n// Testing - ID, name, component (perfect for E2E)\r\ncomponentDebugger({ preset: \"testing\" });\r\n\r\n// Debugging - everything + metadata (full visibility)\r\ncomponentDebugger({ preset: \"debugging\" });\r\n\r\n// Production - privacy-focused with shortened paths\r\ncomponentDebugger({ preset: \"production\" });\r\n```\r\n\r\n**[📚 See all preset details in EXAMPLES.md](./EXAMPLES.md#presets)**\r\n\r\n### Common Configurations\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003e🎯 Clean DOM - Minimal Attributes\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n```typescript\r\ncomponentDebugger({\r\n  includeAttributes: [\"id\", \"name\"], // Only these attributes\r\n});\r\n// Result: Only data-dev-id and data-dev-name\r\n```\r\n\r\n**[See more attribute filtering examples →](./EXAMPLES.md#attribute-filtering)**\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003e🗂️ Path Filtering - Specific Directories\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n```typescript\r\ncomponentDebugger({\r\n  includePaths: [\"src/components/**\", \"src/features/**\"],\r\n  excludePaths: [\"**/*.test.tsx\", \"**/*.stories.tsx\"],\r\n});\r\n```\r\n\r\n**[See path filtering patterns →](./EXAMPLES.md#path-filtering)**\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003e🔧 Privacy - Transform Paths\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n```typescript\r\ncomponentDebugger({\r\n  transformers: {\r\n    path: (p) =\u003e p.split(\"/\").slice(-2).join(\"/\"), // Shorten paths\r\n    id: (id) =\u003e id.split(\":\").slice(-2).join(\":\"), // Remove path from ID\r\n  },\r\n});\r\n```\r\n\r\n**[See transformer examples →](./EXAMPLES.md#attribute-transformers)**\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003e⚡ Conditional - Tag Specific Components\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n```typescript\r\ncomponentDebugger({\r\n  shouldTag: ({ elementName }) =\u003e {\r\n    // Only tag custom components (uppercase)\r\n    return elementName[0] === elementName[0].toUpperCase();\r\n  },\r\n});\r\n```\r\n\r\n**[See conditional tagging patterns →](./EXAMPLES.md#conditional-tagging)**\r\n\r\n\u003c/details\u003e\r\n\r\n\u003e **💡 Pro Tip:** Use `includeAttributes` for cleaner DOM instead of legacy `includeProps`/`includeContent`\r\n\r\n\u003e **⚠️ Gotcha:** When both `includeAttributes` and `excludeAttributes` are set, `includeAttributes` takes priority\r\n\r\n### Configuration Reference\r\n\r\n\u003cdetails open\u003e\r\n\u003csummary\u003e\u003cstrong\u003eCore Options\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n| Option            | Type       | Default            | Description                                                                 |\r\n| ----------------- | ---------- | ------------------ | --------------------------------------------------------------------------- |\r\n| `enabled`         | `boolean`  | `true`             | Enable/disable the plugin                                                   |\r\n| `attributePrefix` | `string`   | `'data-dev'`       | Prefix for data attributes                                                  |\r\n| `extensions`      | `string[]` | `['.jsx', '.tsx']` | File extensions to process                                                  |\r\n| `preset`          | `Preset`   | `undefined`        | Quick config: `'minimal'` \\| `'testing'` \\| `'debugging'` \\| `'production'` |\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003eV2 Features - Attribute Control\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n| Option              | Type              | Default     | Description                                      |\r\n| ------------------- | ----------------- | ----------- | ------------------------------------------------ |\r\n| `includeAttributes` | `AttributeName[]` | `undefined` | **Recommended:** Only include these attributes   |\r\n| `excludeAttributes` | `AttributeName[]` | `undefined` | Exclude these attributes                         |\r\n| `transformers`      | `object`          | `undefined` | Transform attribute values (privacy, formatting) |\r\n| `groupAttributes`   | `boolean`         | `false`     | Combine all into single JSON attribute           |\r\n\r\n**Available:** `'id'`, `'name'`, `'path'`, `'line'`, `'file'`, `'component'`, `'metadata'`\r\n\r\n**[→ Full attribute control examples](./EXAMPLES.md#attribute-filtering)**\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003eV2 Features - Path \u0026 Element Filtering\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n| Option            | Type          | Default                          | Description              |\r\n| ----------------- | ------------- | -------------------------------- | ------------------------ |\r\n| `includePaths`    | `string[]`    | `undefined`                      | Glob patterns to include |\r\n| `excludePaths`    | `string[]`    | `undefined`                      | Glob patterns to exclude |\r\n| `excludeElements` | `string[]`    | `['Fragment', 'React.Fragment']` | Element names to skip    |\r\n| `customExcludes`  | `Set\u003cstring\u003e` | Three.js elements                | Custom elements to skip  |\r\n\r\n**[→ Path filtering patterns](./EXAMPLES.md#path-filtering)**\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003eV2 Features - Conditional \u0026 Custom\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n| Option             | Type                               | Default     | Description                                  |\r\n| ------------------ | ---------------------------------- | ----------- | -------------------------------------------- |\r\n| `shouldTag`        | `(info) =\u003e boolean`                | `undefined` | Conditionally tag components                 |\r\n| `customAttributes` | `(info) =\u003e Record\u003cstring, string\u003e` | `undefined` | Add custom attributes dynamically            |\r\n| `metadataEncoding` | `MetadataEncoding`                 | `'json'`    | Encoding: `'json'` \\| `'base64'` \\| `'none'` |\r\n\r\n**[→ Conditional tagging](./EXAMPLES.md#conditional-tagging)** • **[→ Custom attributes](./EXAMPLES.md#custom-attributes)**\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003eV2 Features - Depth, Stats \u0026 Advanced\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n| Option                  | Type              | Default     | Description             |\r\n| ----------------------- | ----------------- | ----------- | ----------------------- |\r\n| `maxDepth`              | `number`          | `undefined` | Maximum nesting depth   |\r\n| `minDepth`              | `number`          | `undefined` | Minimum nesting depth   |\r\n| `tagOnlyRoots`          | `boolean`         | `false`     | Only tag root elements  |\r\n| `onTransform`           | `(stats) =\u003e void` | `undefined` | Per-file callback       |\r\n| `onComplete`            | `(stats) =\u003e void` | `undefined` | Completion callback     |\r\n| `exportStats`           | `string`          | `undefined` | Export stats to file    |\r\n| `includeSourceMapHints` | `boolean`         | `false`     | Add source map comments |\r\n| `debug`                 | `boolean`         | `false`     | Enable debug logging    |\r\n\r\n**[→ Depth filtering](./EXAMPLES.md#depth-filtering)** • **[→ Statistics](./EXAMPLES.md#statistics--callbacks)**\r\n\r\n\u003c/details\u003e\r\n\r\n\u003e **💡 All v2 features are opt-in** - Existing configs work unchanged\r\n\u003e\r\n\u003e **📖 See complete TypeScript types:** `import { type TagOptions } from 'vite-plugin-component-debugger'`\r\n\r\n**📚 [View 50+ Detailed Examples in EXAMPLES.md →](./EXAMPLES.md)**\r\n\r\nExamples include: E2E testing setups, debug overlays, monorepo configs, feature flags, performance monitoring, and more!\r\n\r\n## Use Cases\r\n\r\n### 1. Development Debugging (Simple)\r\n\r\nFind components in the DOM:\r\n\r\n```javascript\r\n// In browser console\r\ndocument.querySelectorAll('[data-dev-component=\"Button\"]');\r\nconsole.log(\"Button locations:\", [...$$('[data-dev-path*=\"Button\"]')]);\r\n```\r\n\r\n### 2. E2E Testing (Intermediate)\r\n\r\nStable selectors for tests:\r\n\r\n```javascript\r\n// Cypress\r\ncy.get('[data-dev-component=\"SubmitButton\"]').click();\r\ncy.get('[data-dev-path*=\"LoginForm\"]').should(\"be.visible\");\r\n\r\n// Playwright\r\nawait page.click('[data-dev-component=\"SubmitButton\"]');\r\nawait expect(page.locator('[data-dev-path*=\"LoginForm\"]')).toBeVisible();\r\n```\r\n\r\n### 3. Visual Debugging Tools (Advanced)\r\n\r\nBuild custom debugging overlays:\r\n\r\n```javascript\r\n// Show component boundaries on hover\r\ndocument.addEventListener(\"mouseover\", (e) =\u003e {\r\n  const target = e.target;\r\n  if (target.dataset?.devComponent) {\r\n    target.style.outline = \"2px solid red\";\r\n    console.log(`Component: ${target.dataset.devComponent}`);\r\n    console.log(`Location: ${target.dataset.devPath}:${target.dataset.devLine}`);\r\n  }\r\n});\r\n```\r\n\r\n### 4. Performance Monitoring (Expert)\r\n\r\nTrack component render activity:\r\n\r\n```javascript\r\nconst observer = new MutationObserver((mutations) =\u003e {\r\n  mutations.forEach((mutation) =\u003e {\r\n    if (mutation.type === \"childList\") {\r\n      mutation.addedNodes.forEach((node) =\u003e {\r\n        if (node.dataset?.devId) {\r\n          console.log(`Component rendered: ${node.dataset.devId}`);\r\n        }\r\n      });\r\n    }\r\n  });\r\n});\r\n\r\nobserver.observe(document.body, { childList: true, subtree: true });\r\n```\r\n\r\n## Advanced Features\r\n\r\n### Environment-Specific Setup\r\n\r\n```typescript\r\n// Different configs per environment\r\nconst isDev = process.env.NODE_ENV === \"development\";\r\nconst isStaging = process.env.NODE_ENV === \"staging\";\r\n\r\nexport default defineConfig({\r\n  plugins: [\r\n    componentDebugger({\r\n      enabled: isDev || isStaging,\r\n      attributePrefix: isStaging ? \"data-staging\" : \"data-dev\",\r\n      includeProps: isDev, // Enable metadata in development\r\n      includeContent: isDev, // Enable content capture in development\r\n    }),\r\n    react(),\r\n  ],\r\n});\r\n```\r\n\r\n### React Three Fiber Support\r\n\r\nAutomatically excludes Three.js elements:\r\n\r\n```typescript\r\n// Default exclusions\r\ncomponentDebugger({\r\n  customExcludes: new Set([\r\n    \"mesh\",\r\n    \"group\",\r\n    \"scene\",\r\n    \"camera\",\r\n    \"ambientLight\",\r\n    \"directionalLight\",\r\n    \"pointLight\",\r\n    \"boxGeometry\",\r\n    \"sphereGeometry\",\r\n    \"planeGeometry\",\r\n    \"meshBasicMaterial\",\r\n    \"meshStandardMaterial\",\r\n    // ... and many more\r\n  ]),\r\n});\r\n\r\n// To include Three.js elements\r\ncomponentDebugger({\r\n  customExcludes: new Set(), // Empty set = tag everything\r\n});\r\n```\r\n\r\n### TypeScript Support\r\n\r\nFull type definitions included:\r\n\r\n```typescript\r\nimport componentDebugger, { type TagOptions } from \"vite-plugin-component-debugger\";\r\n\r\nconst config: TagOptions = {\r\n  enabled: true,\r\n  attributePrefix: \"data-track\",\r\n};\r\n\r\nexport default defineConfig({\r\n  plugins: [componentDebugger(config), react()],\r\n});\r\n```\r\n\r\n### Build Performance \u0026 Statistics\r\n\r\n```\r\n📊 Component Debugger Statistics:\r\n   Total files scanned: 45\r\n   Files processed: 32\r\n   Elements tagged: 287\r\n```\r\n\r\n**Performance optimizations (v2.2.0):**\r\n\r\n- 🚀 **15-30% faster** than v2.1 with 3 micro-optimizations\r\n- ⚡ **Pre-compiled glob patterns** - 5-10x faster path matching\r\n- 📦 **Optimized JSON serialization** - 2-3x faster metadata encoding\r\n- 🔧 **Smart string operations** - 2x faster debug logging\r\n- **Time savings**: 200-500ms on 100-file projects, 2-5s on 1000-file projects\r\n- Efficient AST traversal with caching\r\n- Minimal HMR impact\r\n- Automatically skips `node_modules`\r\n- Only runs during development\r\n\r\n### Troubleshooting \u0026 Common Gotchas\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003e⚠️ Line numbers are wrong/offset by ~19?\u003c/strong\u003e (Most common issue)\u003c/summary\u003e\r\n\r\n**Problem:** `data-dev-line` shows numbers ~19 higher than expected\r\n\r\n**Cause:** Plugin order is wrong - React plugin adds ~19 lines of imports/HMR setup\r\n\r\n**Fix:** Move `componentDebugger()` BEFORE `react()` in Vite config\r\n\r\n```typescript\r\n// ❌ WRONG - Line numbers will be offset\r\nexport default defineConfig({\r\n  plugins: [\r\n    react(), // Transforms code first, adds ~19 lines\r\n    componentDebugger(), // Gets wrong line numbers\r\n  ],\r\n});\r\n\r\n// ✅ CORRECT - Accurate line numbers\r\nexport default defineConfig({\r\n  plugins: [\r\n    componentDebugger(), // Processes original source first\r\n    react(), // Transforms after tagging\r\n  ],\r\n});\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003eElements not being tagged?\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n1. **Check file extension:** File must match `extensions` (default: `.jsx`, `.tsx`)\r\n2. **Check exclusions:** Element not in `excludeElements` or `customExcludes`\r\n3. **Check paths:** File not excluded by `excludePaths` pattern\r\n4. **Check plugin order:** `componentDebugger()` before `react()`\r\n5. **Check enabled:** Plugin is enabled (`enabled: true`)\r\n6. **Check shouldTag:** If using `shouldTag`, callback must return `true`\r\n\r\n**Debug with:**\r\n\r\n```typescript\r\ncomponentDebugger({\r\n  debug: true, // Shows what's being processed\r\n  enabled: true,\r\n});\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003eBuild performance issues?\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n**Quick fixes:**\r\n\r\n1. Use `includeAttributes` to reduce DOM size:\r\n   ```typescript\r\n   includeAttributes: [\"id\", \"name\"]; // Only essential attributes\r\n   ```\r\n2. Filter paths to only process needed directories:\r\n   ```typescript\r\n   includePaths: ['src/components/**'],\r\n   excludePaths: ['**/*.test.tsx', '**/*.stories.tsx']\r\n   ```\r\n3. Use `maxDepth` to limit deep nesting:\r\n   ```typescript\r\n   maxDepth: 5; // Only tag up to 5 levels deep\r\n   ```\r\n4. Skip test files with `excludePaths`\r\n\r\n**[→ See performance optimization examples](./EXAMPLES.md#performance-monitoring)**\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003eAttributes appearing in production?\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n```typescript\r\ncomponentDebugger({\r\n  enabled: process.env.NODE_ENV !== \"production\",\r\n});\r\n```\r\n\r\nOr use environment-specific configs:\r\n\r\n```typescript\r\nenabled: isDev || isStaging, // Not in production\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003eincludeAttributes vs excludeAttributes priority?\u003c/strong\u003e\u003c/summary\u003e\r\n\r\n**Gotcha:** When both are set, `includeAttributes` takes priority\r\n\r\n```typescript\r\ncomponentDebugger({\r\n  includeAttributes: [\"id\", \"name\", \"line\"],\r\n  excludeAttributes: [\"name\"], // ⚠️ This is IGNORED\r\n});\r\n// Result: Only id, name, line are included\r\n```\r\n\r\n**Best practice:** Use one or the other, not both\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary\u003e\u003cstrong\u003eTypeScript type errors?\u003c/strong\u003e\u003c/summary\u003e\r\n\r\nImport types for full IntelliSense:\r\n\r\n```typescript\r\nimport componentDebugger, {\r\n  type TagOptions,\r\n  type ComponentInfo,\r\n  type AttributeName,\r\n} from \"vite-plugin-component-debugger\";\r\n\r\nconst config: TagOptions = {\r\n  // Full type checking\r\n};\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n## Development \u0026 Contributing\r\n\r\n### Auto-Release Workflow\r\n\r\n🚀 **Every commit to `main` triggers automatic release:**\r\n\r\n**Commit Message → Version Bump:**\r\n\r\n- `BREAKING CHANGE:` or `major:` → Major (1.0.0 → 2.0.0)\r\n- `feat:` or `feature:` or `minor:` → Minor (1.0.0 → 1.1.0)\r\n- Everything else → Patch (1.0.0 → 1.0.1)\r\n\r\n**Example commit messages:**\r\n\r\n```bash\r\n# Major version (breaking changes)\r\ngit commit -m \"BREAKING CHANGE: removed deprecated API\"\r\ngit commit -m \"major: complete rewrite of plugin interface\"\r\n\r\n# Minor version (new features)\r\ngit commit -m \"feat: add TypeScript 5.0 support\"\r\ngit commit -m \"feature: new configuration option for props\"\r\ngit commit -m \"minor: add custom exclude patterns\"\r\n\r\n# Patch version (bug fixes, docs, chores)\r\ngit commit -m \"fix: resolve memory leak in transformer\"\r\ngit commit -m \"docs: update README examples\"\r\ngit commit -m \"chore: update dependencies\"\r\n\r\n# Skip release\r\ngit commit -m \"docs: fix typo [skip ci]\"\r\n```\r\n\r\n**What happens automatically:**\r\n\r\n1. Tests run, package builds\r\n2. Version bump based on commit message\r\n3. GitHub release created with changelog\r\n4. Package published to npm\r\n\r\n**Setup auto-publishing:**\r\n\r\n1. Get NPM token: `npm token create --type=automation`\r\n2. Add to GitHub repo: **Settings** → **Secrets** → `NPM_TOKEN`\r\n3. Commit to `main` branch to trigger first release\r\n\r\n### Contributing\r\n\r\n1. Fork and clone\r\n2. `pnpm install`\r\n3. Make changes and add tests\r\n4. `pnpm run check` (lint + test + build)\r\n5. Commit with semantic message (see above)\r\n6. Open PR\r\n\r\nSee [`.github/COMMIT_CONVENTION.md`](.github/COMMIT_CONVENTION.md) for examples.\r\n\r\n### Development Setup\r\n\r\n```bash\r\ngit clone https://github.com/yourusername/vite-plugin-component-debugger.git\r\ncd vite-plugin-component-debugger\r\npnpm install\r\npnpm run test     # Run tests\r\npnpm run build    # Build package\r\npnpm run check    # Full validation\r\n```\r\n\r\n## Author \u0026 Support\r\n\r\n**Tonye Brown** - Builder, Front-end developer, designer, and performance optimization expert crafting immersive web experiences. Also a Music Producer and Artist.\r\n\r\n**Connect:**\r\n\r\n- 🌐 [Website](https://www.tonyebrown.com)\r\n- 📖 [Plugin Docs](https://www.tonyebrown.com/apps/vite-plugin-component-debugger)\r\n- 🐦 [Twitter](https://www.twitter.com/truevined)\r\n- 💼 [LinkedIn](https://www.linkedin.com/in/tonyeb/)\r\n\r\n**Support This Project:**\r\n\r\n- ⭐ Star this repository\r\n- ☕ [Buy me a coffee](https://www.buymeacoffee.com/tonyebrown)\r\n- 💝 [Sponsor on GitHub](https://github.com/sponsors/canadianeagle)\r\n- 🐛 Report issues or suggest features\r\n- 🤝 Contribute code via pull requests\r\n- 📢 Share with other developers\r\n\r\n## License\r\n\r\nMIT © [Tonye Brown](https://www.tonyebrown.com)\r\n\r\n---\r\n\r\n\u003cdiv align=\"center\"\u003e\r\n\r\n**Made with ❤️ by [Tonye Brown](https://www.tonyebrown.com)**\r\n\r\n_Inspired by [lovable-tagger](https://www.npmjs.com/package/lovable-tagger), enhanced for the Vite ecosystem._\r\n\r\n[![GitHub](https://img.shields.io/badge/GitHub-canadianeagle-181717?style=flat\u0026logo=github)](https://github.com/canadianeagle)\r\n[![Website](https://img.shields.io/badge/Website-tonyebrown.com-4285F4?style=flat\u0026logo=google-chrome\u0026logoColor=white)](https://www.tonyebrown.com)\r\n[![LinkedIn](https://img.shields.io/badge/LinkedIn-tonyeb-0A66C2?style=flat\u0026logo=linkedin)](https://www.linkedin.com/in/tonyeb/)\r\n\r\n**⭐ Star this repo if it helped you!**\r\n\r\n\u003c/div\u003e\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanadianeagle%2Fvite-plugin-component-debugger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcanadianeagle%2Fvite-plugin-component-debugger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanadianeagle%2Fvite-plugin-component-debugger/lists"}