@lirankor/vite-plugin-component-tagger 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +174 -0
- package/dist/index.cjs +2 -0
- package/dist/index.js +48 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 [Your Name]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# @lirankor/vite-plugin-component-tagger
|
|
2
|
+
|
|
3
|
+
A Vite plugin that adds data attributes to JSX elements for debugging and development purposes. This plugin helps developers identify which components and files generated specific DOM elements in the browser's developer tools.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Tags both HTML elements and React components** - Works with `<div>`, `<Button>`, `<Stack>`, etc.
|
|
8
|
+
- **Precise line number tracking** - Shows exact source line where element is defined
|
|
9
|
+
- **Self-closing tag support** - Handles `<Component />` syntax correctly
|
|
10
|
+
- **TypeScript-aware** - Avoids breaking TypeScript generic syntax
|
|
11
|
+
- **Optimized performance** - Only runs during development when explicitly enabled
|
|
12
|
+
- **Clean console output** - Minimal, informative logging
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @lirankor/vite-plugin-component-tagger --save-dev
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Basic Setup
|
|
23
|
+
|
|
24
|
+
Add the plugin to your `vite.config.js` or `vite.config.ts`:
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
import { defineConfig } from 'vite'
|
|
28
|
+
import react from '@vitejs/plugin-react'
|
|
29
|
+
import { componentTagger } from '@lirankor/vite-plugin-component-tagger'
|
|
30
|
+
|
|
31
|
+
export default defineConfig({
|
|
32
|
+
plugins: [
|
|
33
|
+
componentTagger({
|
|
34
|
+
enabled: process.env.NODE_ENV === 'development'
|
|
35
|
+
}),
|
|
36
|
+
react(),
|
|
37
|
+
],
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Conditional Usage (Recommended)
|
|
42
|
+
|
|
43
|
+
For maximum control, create a separate npm script:
|
|
44
|
+
|
|
45
|
+
**package.json:**
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"scripts": {
|
|
49
|
+
"dev": "vite",
|
|
50
|
+
"dev:debug": "ENABLE_COMPONENT_TAGGER=true vite"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**vite.config.js:**
|
|
56
|
+
```javascript
|
|
57
|
+
import { componentTagger } from '@lirankor/vite-plugin-component-tagger'
|
|
58
|
+
|
|
59
|
+
export default defineConfig({
|
|
60
|
+
plugins: [
|
|
61
|
+
componentTagger({
|
|
62
|
+
enabled: process.env.ENABLE_COMPONENT_TAGGER === 'true'
|
|
63
|
+
}),
|
|
64
|
+
react(),
|
|
65
|
+
],
|
|
66
|
+
})
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Then run with component tagging:
|
|
70
|
+
```bash
|
|
71
|
+
npm run dev:debug
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Generated Attributes
|
|
75
|
+
|
|
76
|
+
The plugin adds three data attributes to each JSX element:
|
|
77
|
+
|
|
78
|
+
- `data-dev-component`: The component file name (without extension)
|
|
79
|
+
- `data-dev-file`: Full file path with line number
|
|
80
|
+
- `data-dev-tag`: The HTML/React element tag name
|
|
81
|
+
|
|
82
|
+
### Example Output
|
|
83
|
+
|
|
84
|
+
**Source code (Button.jsx:15):**
|
|
85
|
+
```jsx
|
|
86
|
+
export function Button({ children }) {
|
|
87
|
+
return <button className="btn">{children}</button>
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Generated HTML:**
|
|
92
|
+
```html
|
|
93
|
+
<button
|
|
94
|
+
class="btn"
|
|
95
|
+
data-dev-component="Button"
|
|
96
|
+
data-dev-file="/src/components/Button.jsx:15"
|
|
97
|
+
data-dev-tag="button"
|
|
98
|
+
>
|
|
99
|
+
Click me
|
|
100
|
+
</button>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Configuration
|
|
104
|
+
|
|
105
|
+
### Options
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
interface ComponentTaggerOptions {
|
|
109
|
+
enabled?: boolean; // Default: true
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Advanced Configuration
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
componentTagger({
|
|
117
|
+
enabled: process.env.NODE_ENV === 'development' && process.env.DEBUG_COMPONENTS === 'true'
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Use Cases
|
|
122
|
+
|
|
123
|
+
### 1. Component Debugging
|
|
124
|
+
Quickly identify which React component generated a specific DOM element:
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
// In browser console
|
|
128
|
+
const element = document.querySelector('.some-class')
|
|
129
|
+
console.log(element.dataset.devComponent) // "UserProfile"
|
|
130
|
+
console.log(element.dataset.devFile) // "/src/components/UserProfile.jsx:42"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 2. Visual Testing
|
|
134
|
+
Perfect for visual regression testing and component identification in automated tests.
|
|
135
|
+
|
|
136
|
+
### 3. Code Reviews
|
|
137
|
+
Help reviewers understand the relationship between DOM structure and source code.
|
|
138
|
+
|
|
139
|
+
## Important Notes
|
|
140
|
+
|
|
141
|
+
- **Development only**: This plugin should only be enabled during development
|
|
142
|
+
- **Build size**: Has zero impact on production builds when disabled
|
|
143
|
+
- **Performance**: Minimal overhead - only processes JSX/TSX files
|
|
144
|
+
- **Syntax safety**: Carefully avoids breaking TypeScript generics and complex JSX
|
|
145
|
+
|
|
146
|
+
## Debugging
|
|
147
|
+
|
|
148
|
+
The plugin provides helpful console output:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
Component Tagger: Tagged 156 elements across 23 files
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Requirements
|
|
155
|
+
|
|
156
|
+
- Vite 4.0.0 or higher
|
|
157
|
+
- TypeScript/JavaScript project with JSX/TSX files
|
|
158
|
+
|
|
159
|
+
## Contributing
|
|
160
|
+
|
|
161
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
166
|
+
|
|
167
|
+
## Related
|
|
168
|
+
|
|
169
|
+
- [Vite Plugin Documentation](https://vitejs.dev/guide/api-plugin.html)
|
|
170
|
+
- [React Developer Tools](https://github.com/facebook/react/tree/main/packages/react-devtools)
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
Made for the React/Vite community
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function x(f={}){const{enabled:c=!0}=f;if(!c)return{name:"jsx-component-tagger-disabled"};let o=0,n=0;return{name:"jsx-component-tagger",enforce:"pre",buildStart(){o=0,n=0},buildEnd(){n>0&&console.log(`🏷️ Component Tagger: Tagged ${o} elements across ${n} files`)},transform(m,t){if(!c||!t.includes(".tsx")&&!t.includes(".jsx")||t.includes("node_modules"))return null;try{const a=t.split("/").pop()?.replace(/\.(tsx|jsx)$/,"")||"unknown",g=t.replace(process.cwd(),"");let r=m,i=!1,d=0;return[new RegExp("(?<![:\\w])\\s*(<(div|span|p|h[1-6]|button|form|section|main|article|header|footer|nav|aside|[A-Z][a-zA-Z0-9]*(?:[A-Z][a-zA-Z0-9]*)?)(\\s[^>]*?)?(\\/?)>)","g")].forEach(p=>{r=r.replace(p,(s,e,b,A,C,h)=>{const v=(r.substring(0,h).match(/\n/g)||[]).length+1;if(e.includes("data-dev-component")||e.includes("=>")||e.includes("() =>")||e.includes(`
|
|
2
|
+
`))return s;const u=` data-dev-component="${a}" data-dev-file="${g}:${v}" data-dev-tag="${b}"`;let l;e.endsWith("/>")?l=e.slice(0,-2)+u+" />":l=e.slice(0,-1)+u+">";const $=s.replace(e,l);return i=!0,d++,$})}),i?(o+=d,n++,{code:r,map:null}):null}catch(a){return console.warn(`JSX tagger failed for ${t}:`,a),null}}}}exports.componentTagger=x;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
function w(f = {}) {
|
|
2
|
+
const { enabled: c = !0 } = f;
|
|
3
|
+
if (!c)
|
|
4
|
+
return {
|
|
5
|
+
name: "jsx-component-tagger-disabled"
|
|
6
|
+
};
|
|
7
|
+
let o = 0, n = 0;
|
|
8
|
+
return {
|
|
9
|
+
name: "jsx-component-tagger",
|
|
10
|
+
enforce: "pre",
|
|
11
|
+
// Run before esbuild and other core plugins
|
|
12
|
+
buildStart() {
|
|
13
|
+
o = 0, n = 0;
|
|
14
|
+
},
|
|
15
|
+
buildEnd() {
|
|
16
|
+
n > 0 && console.log(`🏷️ Component Tagger: Tagged ${o} elements across ${n} files`);
|
|
17
|
+
},
|
|
18
|
+
transform(m, t) {
|
|
19
|
+
if (!c || !t.includes(".tsx") && !t.includes(".jsx") || t.includes("node_modules"))
|
|
20
|
+
return null;
|
|
21
|
+
try {
|
|
22
|
+
const a = t.split("/").pop()?.replace(/\.(tsx|jsx)$/, "") || "unknown", p = t.replace(process.cwd(), "");
|
|
23
|
+
let r = m, i = !1, d = 0;
|
|
24
|
+
return [new RegExp("(?<![:\\w])\\s*(<(div|span|p|h[1-6]|button|form|section|main|article|header|footer|nav|aside|[A-Z][a-zA-Z0-9]*(?:[A-Z][a-zA-Z0-9]*)?)(\\s[^>]*?)?(\\/?)>)", "g")].forEach((g) => {
|
|
25
|
+
r = r.replace(g, (s, e, b, A, C, h) => {
|
|
26
|
+
const $ = (r.substring(0, h).match(/\n/g) || []).length + 1;
|
|
27
|
+
if (e.includes("data-dev-component") || e.includes("=>") || e.includes("() =>") || e.includes(`
|
|
28
|
+
`))
|
|
29
|
+
return s;
|
|
30
|
+
const u = ` data-dev-component="${a}" data-dev-file="${p}:${$}" data-dev-tag="${b}"`;
|
|
31
|
+
let l;
|
|
32
|
+
e.endsWith("/>") ? l = e.slice(0, -2) + u + " />" : l = e.slice(0, -1) + u + ">";
|
|
33
|
+
const v = s.replace(e, l);
|
|
34
|
+
return i = !0, d++, v;
|
|
35
|
+
});
|
|
36
|
+
}), i ? (o += d, n++, {
|
|
37
|
+
code: r,
|
|
38
|
+
map: null
|
|
39
|
+
}) : null;
|
|
40
|
+
} catch (a) {
|
|
41
|
+
return console.warn(`JSX tagger failed for ${t}:`, a), null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
w as componentTagger
|
|
48
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lirankor/vite-plugin-component-tagger",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "A Vite plugin that adds data attributes to JSX elements for debugging and development purposes",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc && vite build",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"prepublishOnly": "npm run build",
|
|
23
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"vite",
|
|
27
|
+
"plugin",
|
|
28
|
+
"vite-plugin",
|
|
29
|
+
"react",
|
|
30
|
+
"jsx",
|
|
31
|
+
"tsx",
|
|
32
|
+
"debugging",
|
|
33
|
+
"development",
|
|
34
|
+
"devtools",
|
|
35
|
+
"component",
|
|
36
|
+
"tagging",
|
|
37
|
+
"data-attributes",
|
|
38
|
+
"inspector",
|
|
39
|
+
"dom-debugging"
|
|
40
|
+
],
|
|
41
|
+
"author": "Liran Koren",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/lirankor/vite-plugin-component-tagger.git"
|
|
46
|
+
},
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/lirankor/vite-plugin-component-tagger/issues"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/lirankor/vite-plugin-component-tagger#readme",
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"vite": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/node": "^22.19.1",
|
|
56
|
+
"typescript": "~5.9.3",
|
|
57
|
+
"vite": "^7.2.2"
|
|
58
|
+
}
|
|
59
|
+
}
|