react-code-locator 0.1.14 → 0.1.16
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/README.md +54 -0
- package/dist/babel.cjs +11 -197
- package/dist/babel.cjs.map +1 -1
- package/dist/babel.js +11 -197
- package/dist/babel.js.map +1 -1
- package/dist/babelInjectComponentSource.cjs +11 -197
- package/dist/babelInjectComponentSource.cjs.map +1 -1
- package/dist/babelInjectComponentSource.js +11 -197
- package/dist/babelInjectComponentSource.js.map +1 -1
- package/dist/esbuild.cjs +11 -197
- package/dist/esbuild.cjs.map +1 -1
- package/dist/esbuild.js +11 -197
- package/dist/esbuild.js.map +1 -1
- package/dist/swc.cjs +11 -197
- package/dist/swc.cjs.map +1 -1
- package/dist/swc.js +11 -197
- package/dist/swc.js.map +1 -1
- package/dist/unplugin.cjs +308 -0
- package/dist/unplugin.cjs.map +1 -0
- package/dist/unplugin.d.cts +52 -0
- package/dist/unplugin.d.ts +52 -0
- package/dist/unplugin.js +278 -0
- package/dist/unplugin.js.map +1 -0
- package/dist/vite.cjs +11 -197
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.js +11 -197
- package/dist/vite.js.map +1 -1
- package/package.json +28 -2
package/dist/unplugin.js
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
// src/unplugin.ts
|
|
2
|
+
import { createUnplugin } from "unplugin";
|
|
3
|
+
|
|
4
|
+
// src/core/transform.ts
|
|
5
|
+
import { parse } from "acorn";
|
|
6
|
+
import { generate } from "astring";
|
|
7
|
+
import { walk } from "estree-walker";
|
|
8
|
+
|
|
9
|
+
// src/constants.ts
|
|
10
|
+
var SOURCE_PROP = "__componentSourceLoc";
|
|
11
|
+
var JSX_SOURCE_PROP = "$componentSourceLoc";
|
|
12
|
+
var JSX_SOURCE_REGISTRY_SYMBOL = "react-code-locator.jsxSourceRegistry";
|
|
13
|
+
|
|
14
|
+
// src/core/transform.ts
|
|
15
|
+
function toRelativeSource(filename, loc, projectRoot) {
|
|
16
|
+
const root = projectRoot || process.cwd();
|
|
17
|
+
const relativePath = filename.startsWith(root) ? filename.slice(root.length + 1) : filename;
|
|
18
|
+
return `${relativePath}:${loc.line}:${loc.column + 1}`;
|
|
19
|
+
}
|
|
20
|
+
function isComponentName(name) {
|
|
21
|
+
return /^[A-Z]/.test(name);
|
|
22
|
+
}
|
|
23
|
+
function isReactElementFactoryCall(node) {
|
|
24
|
+
const callee = node.callee;
|
|
25
|
+
if (callee.type === "Identifier") {
|
|
26
|
+
const name = callee.name;
|
|
27
|
+
return [
|
|
28
|
+
"jsx",
|
|
29
|
+
"jsxs",
|
|
30
|
+
"jsxDEV",
|
|
31
|
+
"_jsx",
|
|
32
|
+
"_jsxs",
|
|
33
|
+
"_jsxDEV",
|
|
34
|
+
"createElement"
|
|
35
|
+
].includes(name);
|
|
36
|
+
}
|
|
37
|
+
if (callee.type === "MemberExpression") {
|
|
38
|
+
const obj = callee.object;
|
|
39
|
+
const prop = callee.property;
|
|
40
|
+
if (obj.type === "Identifier" && obj.name === "React" && prop.type === "Identifier" && prop.name === "createElement") {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
function isSupportedComponentInit(node) {
|
|
47
|
+
if (!node) return false;
|
|
48
|
+
if (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
if (node.type !== "CallExpression") return false;
|
|
52
|
+
const callee = node.callee;
|
|
53
|
+
if (callee.type === "Identifier") {
|
|
54
|
+
return ["memo", "forwardRef"].includes(callee.name);
|
|
55
|
+
}
|
|
56
|
+
if (callee.type === "MemberExpression") {
|
|
57
|
+
const obj = callee.object;
|
|
58
|
+
const prop = callee.property;
|
|
59
|
+
if (obj.type === "Identifier" && obj.name === "React" && prop.type === "Identifier") {
|
|
60
|
+
return ["memo", "forwardRef"].includes(prop.name);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
function createSourceAssignment(name, sourceValue) {
|
|
66
|
+
return {
|
|
67
|
+
type: "ExpressionStatement",
|
|
68
|
+
expression: {
|
|
69
|
+
type: "AssignmentExpression",
|
|
70
|
+
operator: "=",
|
|
71
|
+
left: {
|
|
72
|
+
type: "MemberExpression",
|
|
73
|
+
object: { type: "Identifier", name },
|
|
74
|
+
property: { type: "Identifier", name: SOURCE_PROP },
|
|
75
|
+
computed: false
|
|
76
|
+
},
|
|
77
|
+
right: { type: "Literal", value: sourceValue }
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function createMarkElementHelper() {
|
|
82
|
+
const code = `
|
|
83
|
+
function _markReactElementSource(element, source) {
|
|
84
|
+
const registryKey = Symbol.for("${JSX_SOURCE_REGISTRY_SYMBOL}");
|
|
85
|
+
let registry = globalThis[registryKey];
|
|
86
|
+
if (!(registry instanceof WeakMap)) {
|
|
87
|
+
registry = globalThis[registryKey] = new WeakMap();
|
|
88
|
+
}
|
|
89
|
+
if (element && typeof element === "object" && typeof element.props === "object") {
|
|
90
|
+
registry.set(element.props, source);
|
|
91
|
+
}
|
|
92
|
+
return element;
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
return parse(code, { ecmaVersion: "latest" }).body[0];
|
|
96
|
+
}
|
|
97
|
+
function wrapWithMarkElement(node, sourceValue) {
|
|
98
|
+
return {
|
|
99
|
+
type: "CallExpression",
|
|
100
|
+
callee: { type: "Identifier", name: "_markReactElementSource" },
|
|
101
|
+
arguments: [node, { type: "Literal", value: sourceValue }],
|
|
102
|
+
optional: false
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function transformSource(code, options) {
|
|
106
|
+
const {
|
|
107
|
+
filename,
|
|
108
|
+
projectRoot = process.cwd(),
|
|
109
|
+
injectJsxSource = true,
|
|
110
|
+
injectComponentSource = true
|
|
111
|
+
} = options;
|
|
112
|
+
let ast;
|
|
113
|
+
try {
|
|
114
|
+
ast = parse(code, {
|
|
115
|
+
ecmaVersion: "latest",
|
|
116
|
+
sourceType: "module",
|
|
117
|
+
ecmaFeatures: { jsx: true },
|
|
118
|
+
locations: true,
|
|
119
|
+
ranges: true
|
|
120
|
+
});
|
|
121
|
+
} catch (err) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
let modified = false;
|
|
125
|
+
let needsHelper = false;
|
|
126
|
+
const seenComponents = /* @__PURE__ */ new Set();
|
|
127
|
+
const assignments = [];
|
|
128
|
+
walk(ast, {
|
|
129
|
+
enter(node, parent, key, index) {
|
|
130
|
+
if (injectJsxSource && node.type === "CallExpression") {
|
|
131
|
+
if (isReactElementFactoryCall(node)) {
|
|
132
|
+
const loc = node.loc;
|
|
133
|
+
if (loc) {
|
|
134
|
+
const sourceValue = toRelativeSource(filename, loc.start, projectRoot);
|
|
135
|
+
const wrapped = wrapWithMarkElement(node, sourceValue);
|
|
136
|
+
this.replace(wrapped);
|
|
137
|
+
needsHelper = true;
|
|
138
|
+
modified = true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (injectJsxSource && node.type === "JSXElement") {
|
|
143
|
+
const opening = node.openingElement;
|
|
144
|
+
const loc = opening.loc;
|
|
145
|
+
if (loc) {
|
|
146
|
+
const sourceValue = toRelativeSource(filename, loc.start, projectRoot);
|
|
147
|
+
const name = opening.name;
|
|
148
|
+
if (name.type === "JSXIdentifier") {
|
|
149
|
+
if (name.name[0] === name.name[0].toLowerCase()) {
|
|
150
|
+
} else {
|
|
151
|
+
const sourceAttr = {
|
|
152
|
+
type: "JSXAttribute",
|
|
153
|
+
name: { type: "JSXIdentifier", name: JSX_SOURCE_PROP },
|
|
154
|
+
value: { type: "Literal", value: sourceValue }
|
|
155
|
+
};
|
|
156
|
+
opening.attributes.push(sourceAttr);
|
|
157
|
+
modified = true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (injectComponentSource && node.type === "FunctionDeclaration") {
|
|
163
|
+
const name = node.id?.name;
|
|
164
|
+
if (name && isComponentName(name) && !seenComponents.has(name)) {
|
|
165
|
+
const loc = node.loc;
|
|
166
|
+
if (loc) {
|
|
167
|
+
const sourceValue = toRelativeSource(filename, loc.start, projectRoot);
|
|
168
|
+
const assignment = createSourceAssignment(name, sourceValue);
|
|
169
|
+
assignments.push({ node, parent, assignment });
|
|
170
|
+
seenComponents.add(name);
|
|
171
|
+
modified = true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (injectComponentSource && node.type === "VariableDeclarator") {
|
|
176
|
+
const id = node.id;
|
|
177
|
+
if (id.type === "Identifier" && isComponentName(id.name) && !seenComponents.has(id.name)) {
|
|
178
|
+
const init = node.init;
|
|
179
|
+
if (init && isSupportedComponentInit(init)) {
|
|
180
|
+
const loc = node.loc || init.loc;
|
|
181
|
+
if (loc) {
|
|
182
|
+
const sourceValue = toRelativeSource(filename, loc.start, projectRoot);
|
|
183
|
+
const assignment = createSourceAssignment(id.name, sourceValue);
|
|
184
|
+
assignments.push({ node, parent, assignment });
|
|
185
|
+
seenComponents.add(id.name);
|
|
186
|
+
modified = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
if (!modified) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
if (needsHelper) {
|
|
197
|
+
const helper = createMarkElementHelper();
|
|
198
|
+
const exists = ast.body.some(
|
|
199
|
+
(n) => n.type === "FunctionDeclaration" && n.id?.name === "_markReactElementSource"
|
|
200
|
+
);
|
|
201
|
+
if (!exists) {
|
|
202
|
+
ast.body.unshift(helper);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
for (const { node, parent, assignment } of assignments.reverse()) {
|
|
206
|
+
if (parent && parent.type === "Program") {
|
|
207
|
+
const index = ast.body.indexOf(node);
|
|
208
|
+
if (index !== -1) {
|
|
209
|
+
ast.body.splice(index + 1, 0, assignment);
|
|
210
|
+
}
|
|
211
|
+
} else if (parent && parent.type === "ExportNamedDeclaration") {
|
|
212
|
+
const exportParent = ast.body.find(
|
|
213
|
+
(n) => n.type === "ExportNamedDeclaration" && n.declaration === parent
|
|
214
|
+
);
|
|
215
|
+
if (exportParent) {
|
|
216
|
+
const index = ast.body.indexOf(exportParent);
|
|
217
|
+
ast.body.splice(index + 1, 0, assignment);
|
|
218
|
+
}
|
|
219
|
+
} else if (parent && parent.type === "ExportDefaultDeclaration") {
|
|
220
|
+
const index = ast.body.indexOf(parent);
|
|
221
|
+
ast.body.splice(index + 1, 0, assignment);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const result = generate(ast, { indent: " " });
|
|
225
|
+
return { code: result };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/unplugin.ts
|
|
229
|
+
var DEFAULT_INCLUDE = /\.([jt]sx)$/;
|
|
230
|
+
var DEFAULT_EXCLUDE = /node_modules/;
|
|
231
|
+
function shouldTransform(id, include, exclude) {
|
|
232
|
+
const includePatterns = Array.isArray(include) ? include : [include];
|
|
233
|
+
const excludePatterns = Array.isArray(exclude) ? exclude : [exclude];
|
|
234
|
+
if (excludePatterns.some((pattern) => pattern.test(id))) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
return includePatterns.some((pattern) => pattern.test(id));
|
|
238
|
+
}
|
|
239
|
+
var unplugin = createUnplugin((options = {}) => {
|
|
240
|
+
const {
|
|
241
|
+
include = DEFAULT_INCLUDE,
|
|
242
|
+
exclude = DEFAULT_EXCLUDE,
|
|
243
|
+
projectRoot = process.cwd(),
|
|
244
|
+
injectComponentSource = true,
|
|
245
|
+
injectJsxSource = true
|
|
246
|
+
} = options;
|
|
247
|
+
return {
|
|
248
|
+
name: "react-code-locator",
|
|
249
|
+
transform(code, id) {
|
|
250
|
+
if (!shouldTransform(id, include, exclude)) {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
const result = transformSource(code, {
|
|
254
|
+
filename: id,
|
|
255
|
+
projectRoot,
|
|
256
|
+
injectComponentSource,
|
|
257
|
+
injectJsxSource
|
|
258
|
+
});
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
});
|
|
263
|
+
var vitePlugin = unplugin.vite;
|
|
264
|
+
var webpackPlugin = unplugin.webpack;
|
|
265
|
+
var rollupPlugin = unplugin.rollup;
|
|
266
|
+
var esbuildPlugin = unplugin.esbuild;
|
|
267
|
+
var rspackPlugin = unplugin.rspack;
|
|
268
|
+
var unplugin_default = unplugin;
|
|
269
|
+
export {
|
|
270
|
+
unplugin_default as default,
|
|
271
|
+
esbuildPlugin,
|
|
272
|
+
rollupPlugin,
|
|
273
|
+
rspackPlugin,
|
|
274
|
+
unplugin,
|
|
275
|
+
vitePlugin,
|
|
276
|
+
webpackPlugin
|
|
277
|
+
};
|
|
278
|
+
//# sourceMappingURL=unplugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/unplugin.ts","../src/core/transform.ts","../src/constants.ts"],"sourcesContent":["/**\n * Unplugin-based universal adapter for all build tools\n * Supports: Vite, Webpack, Rollup, esbuild, Rspack\n * \n * Zero-dependency transform using acorn instead of Babel\n */\n\nimport { createUnplugin, type UnpluginInstance, type UnpluginOptions } from \"unplugin\";\nimport { transformSource, type TransformOptions } from \"./core/transform\";\n\nexport interface ReactCodeLocatorOptions extends Omit<TransformOptions, 'filename'> {\n /** \n * Enable source transform for component definitions\n * @default true\n */\n injectComponentSource?: boolean;\n \n /** \n * Enable source transform for JSX call sites\n * @default true\n */\n injectJsxSource?: boolean;\n \n /**\n * Project root for relative path calculation\n * @default process.cwd()\n */\n projectRoot?: string;\n \n /**\n * Include filter for file paths\n * @default /\\.[jt]sx$/\n */\n include?: RegExp | RegExp[];\n \n /**\n * Exclude filter for file paths\n * @default /node_modules/\n */\n exclude?: RegExp | RegExp[];\n}\n\nexport type { TransformOptions };\n\nconst DEFAULT_INCLUDE = /\\.([jt]sx)$/;\nconst DEFAULT_EXCLUDE = /node_modules/;\n\nfunction shouldTransform(id: string, include: RegExp | RegExp[], exclude: RegExp | RegExp[]): boolean {\n const includePatterns = Array.isArray(include) ? include : [include];\n const excludePatterns = Array.isArray(exclude) ? exclude : [exclude];\n \n // Check exclude first\n if (excludePatterns.some(pattern => pattern.test(id))) {\n return false;\n }\n \n // Then check include\n return includePatterns.some(pattern => pattern.test(id));\n}\n\nexport const unplugin: UnpluginInstance<ReactCodeLocatorOptions | undefined, false> = \n createUnplugin((options = {}) => {\n const {\n include = DEFAULT_INCLUDE,\n exclude = DEFAULT_EXCLUDE,\n projectRoot = process.cwd(),\n injectComponentSource = true,\n injectJsxSource = true,\n } = options;\n\n return {\n name: \"react-code-locator\",\n \n transform(code, id) {\n // Skip if doesn't match patterns\n if (!shouldTransform(id, include, exclude)) {\n return null;\n }\n\n // Perform transform using acorn (zero-dependency)\n const result = transformSource(code, {\n filename: id,\n projectRoot,\n injectComponentSource,\n injectJsxSource,\n });\n\n return result;\n },\n } as UnpluginOptions;\n });\n\n// Export individual build tool adapters\nexport const vitePlugin = unplugin.vite;\nexport const webpackPlugin = unplugin.webpack;\nexport const rollupPlugin = unplugin.rollup;\nexport const esbuildPlugin = unplugin.esbuild;\nexport const rspackPlugin = unplugin.rspack;\n\n// Default export for direct usage\nexport default unplugin;\n","/**\n * Zero-dependency source transform using acorn\n * No Babel required - pure JavaScript AST manipulation\n */\n\nimport { parse, type Node as AcornNode } from \"acorn\";\nimport { generate } from \"astring\";\nimport { walk } from \"estree-walker\";\nimport type {\n Node,\n Program,\n FunctionDeclaration,\n FunctionExpression,\n ArrowFunctionExpression,\n VariableDeclarator,\n CallExpression,\n MemberExpression,\n Identifier,\n ExpressionStatement,\n AssignmentExpression,\n} from \"estree\";\nimport { SOURCE_PROP, JSX_SOURCE_PROP, JSX_SOURCE_REGISTRY_SYMBOL } from \"../constants\";\n\nexport interface TransformOptions {\n filename: string;\n projectRoot?: string;\n injectJsxSource?: boolean;\n injectComponentSource?: boolean;\n}\n\ninterface Location {\n line: number;\n column: number;\n}\n\nfunction toRelativeSource(filename: string, loc: Location, projectRoot?: string): string {\n const root = projectRoot || process.cwd();\n const relativePath = filename.startsWith(root) \n ? filename.slice(root.length + 1) \n : filename;\n return `${relativePath}:${loc.line}:${loc.column + 1}`;\n}\n\nfunction isComponentName(name: string): boolean {\n return /^[A-Z]/.test(name);\n}\n\nfunction isReactElementFactoryCall(node: CallExpression): boolean {\n const callee = node.callee;\n \n if (callee.type === \"Identifier\") {\n const name = callee.name;\n return [\n \"jsx\", \"jsxs\", \"jsxDEV\",\n \"_jsx\", \"_jsxs\", \"_jsxDEV\",\n \"createElement\"\n ].includes(name);\n }\n \n // React.createElement\n if (callee.type === \"MemberExpression\") {\n const obj = callee.object;\n const prop = callee.property;\n if (obj.type === \"Identifier\" && obj.name === \"React\" && \n prop.type === \"Identifier\" && prop.name === \"createElement\") {\n return true;\n }\n }\n \n return false;\n}\n\nfunction isSupportedComponentInit(\n node: Node | null\n): boolean {\n if (!node) return false;\n \n if (node.type === \"ArrowFunctionExpression\" || \n node.type === \"FunctionExpression\") {\n return true;\n }\n \n if (node.type !== \"CallExpression\") return false;\n \n const callee = node.callee;\n if (callee.type === \"Identifier\") {\n return [\"memo\", \"forwardRef\"].includes(callee.name);\n }\n \n // React.memo, React.forwardRef\n if (callee.type === \"MemberExpression\") {\n const obj = callee.object;\n const prop = callee.property;\n if (obj.type === \"Identifier\" && obj.name === \"React\" && \n prop.type === \"Identifier\") {\n return [\"memo\", \"forwardRef\"].includes(prop.name);\n }\n }\n \n return false;\n}\n\nfunction createSourceAssignment(name: string, sourceValue: string): ExpressionStatement {\n return {\n type: \"ExpressionStatement\",\n expression: {\n type: \"AssignmentExpression\",\n operator: \"=\",\n left: {\n type: \"MemberExpression\",\n object: { type: \"Identifier\", name },\n property: { type: \"Identifier\", name: SOURCE_PROP },\n computed: false,\n } as MemberExpression,\n right: { type: \"Literal\", value: sourceValue },\n } as AssignmentExpression,\n };\n}\n\nfunction createMarkElementHelper(): FunctionDeclaration {\n const code = `\nfunction _markReactElementSource(element, source) {\n const registryKey = Symbol.for(\"${JSX_SOURCE_REGISTRY_SYMBOL}\");\n let registry = globalThis[registryKey];\n if (!(registry instanceof WeakMap)) {\n registry = globalThis[registryKey] = new WeakMap();\n }\n if (element && typeof element === \"object\" && typeof element.props === \"object\") {\n registry.set(element.props, source);\n }\n return element;\n}\n`;\n return parse(code, { ecmaVersion: \"latest\" }).body[0] as FunctionDeclaration;\n}\n\nfunction wrapWithMarkElement(\n node: Node,\n sourceValue: string\n): CallExpression {\n return {\n type: \"CallExpression\",\n callee: { type: \"Identifier\", name: \"_markReactElementSource\" },\n arguments: [node as any, { type: \"Literal\", value: sourceValue }],\n optional: false,\n };\n}\n\nexport function transformSource(\n code: string,\n options: TransformOptions\n): { code: string; map?: any } | null {\n const {\n filename,\n projectRoot = process.cwd(),\n injectJsxSource = true,\n injectComponentSource = true,\n } = options;\n\n // Parse with acorn\n let ast: Program;\n try {\n ast = parse(code, {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n ecmaFeatures: { jsx: true },\n locations: true,\n ranges: true,\n } as any) as Program;\n } catch (err) {\n // Parse error - return null to skip this file\n return null;\n }\n\n let modified = false;\n let needsHelper = false;\n const seenComponents = new Set<string>();\n const assignments: Array<{ node: Node; parent: Node | null; assignment: ExpressionStatement }> = [];\n\n walk(ast as any, {\n enter(node: any, parent: any, key: any, index: any) {\n // Inject JSX source for element factory calls\n if (injectJsxSource && node.type === \"CallExpression\") {\n if (isReactElementFactoryCall(node)) {\n const loc = node.loc;\n if (loc) {\n const sourceValue = toRelativeSource(filename, loc.start, projectRoot);\n const wrapped = wrapWithMarkElement(node, sourceValue);\n \n // Replace the node\n this.replace(wrapped);\n needsHelper = true;\n modified = true;\n }\n }\n }\n\n // Inject JSX source for JSX elements\n if (injectJsxSource && node.type === \"JSXElement\") {\n const opening = node.openingElement;\n const loc = opening.loc;\n \n if (loc) {\n const sourceValue = toRelativeSource(filename, loc.start, projectRoot);\n \n // Check if intrinsic element (lowercase) or component (uppercase)\n const name = opening.name;\n if (name.type === \"JSXIdentifier\") {\n if (name.name[0] === name.name[0].toLowerCase()) {\n // Intrinsic element - use _markReactElementSource\n // This is handled by the CallExpression visitor for jsx()\n // But for JSX syntax directly, we need different handling\n } else {\n // Component - add $componentSourceLoc prop\n const sourceAttr = {\n type: \"JSXAttribute\",\n name: { type: \"JSXIdentifier\", name: JSX_SOURCE_PROP },\n value: { type: \"Literal\", value: sourceValue },\n };\n opening.attributes.push(sourceAttr);\n modified = true;\n }\n }\n }\n }\n\n // Inject component source for function declarations\n if (injectComponentSource && node.type === \"FunctionDeclaration\") {\n const name = node.id?.name;\n if (name && isComponentName(name) && !seenComponents.has(name)) {\n const loc = node.loc;\n if (loc) {\n const sourceValue = toRelativeSource(filename, loc.start, projectRoot);\n const assignment = createSourceAssignment(name, sourceValue);\n assignments.push({ node, parent, assignment });\n seenComponents.add(name);\n modified = true;\n }\n }\n }\n\n // Inject component source for variable declarations\n if (injectComponentSource && node.type === \"VariableDeclarator\") {\n const id = node.id;\n if (id.type === \"Identifier\" && isComponentName(id.name) && !seenComponents.has(id.name)) {\n const init = node.init;\n if (init && isSupportedComponentInit(init)) {\n const loc = node.loc || init.loc;\n if (loc) {\n const sourceValue = toRelativeSource(filename, loc.start, projectRoot);\n const assignment = createSourceAssignment(id.name, sourceValue);\n assignments.push({ node, parent, assignment });\n seenComponents.add(id.name);\n modified = true;\n }\n }\n }\n }\n },\n });\n\n if (!modified) {\n return null;\n }\n\n // Insert helper function if needed\n if (needsHelper) {\n const helper = createMarkElementHelper();\n // Check if already exists\n const exists = ast.body.some(\n (n) => n.type === \"FunctionDeclaration\" && \n n.id?.name === \"_markReactElementSource\"\n );\n if (!exists) {\n ast.body.unshift(helper);\n }\n }\n\n // Insert component source assignments\n // We need to insert after the declaration, so we process in reverse order\n for (const { node, parent, assignment } of assignments.reverse()) {\n if (parent && parent.type === \"Program\") {\n const index = ast.body.indexOf(node as any);\n if (index !== -1) {\n ast.body.splice(index + 1, 0, assignment as any);\n }\n } else if (parent && parent.type === \"ExportNamedDeclaration\") {\n // For export const Component = ...\n // Insert after the export statement\n const exportParent = (ast as any).body.find((n: any) => \n n.type === \"ExportNamedDeclaration\" && n.declaration === parent\n );\n if (exportParent) {\n const index = ast.body.indexOf(exportParent);\n ast.body.splice(index + 1, 0, assignment as any);\n }\n } else if (parent && parent.type === \"ExportDefaultDeclaration\") {\n // For export default function Component() ...\n const index = ast.body.indexOf(parent as any);\n ast.body.splice(index + 1, 0, assignment as any);\n }\n }\n\n // Generate code\n const result = generate(ast as any, { indent: \" \" });\n\n return { code: result };\n}\n","export const SOURCE_PROP = \"__componentSourceLoc\";\nexport const JSX_SOURCE_PROP = \"$componentSourceLoc\";\nexport const JSX_SOURCE_REGISTRY_SYMBOL = \"react-code-locator.jsxSourceRegistry\";\n"],"mappings":"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","names":[]}
|
package/dist/vite.cjs
CHANGED
|
@@ -42,7 +42,6 @@ var import_core = require("@babel/core");
|
|
|
42
42
|
|
|
43
43
|
// src/constants.ts
|
|
44
44
|
var SOURCE_PROP = "__componentSourceLoc";
|
|
45
|
-
var JSX_SOURCE_PROP = "$componentSourceLoc";
|
|
46
45
|
var JSX_SOURCE_REGISTRY_SYMBOL = "react-code-locator.jsxSourceRegistry";
|
|
47
46
|
|
|
48
47
|
// src/sourceMetadata.ts
|
|
@@ -82,43 +81,11 @@ function toRelativeSource(filename, loc, projectRoot) {
|
|
|
82
81
|
const relPath = root && normalizedFilename.startsWith(`${root}/`) ? normalizedFilename.slice(root.length + 1) : root ? computeRelativePath(root, normalizedFilename) : normalizedFilename;
|
|
83
82
|
return `${relPath}:${loc.line}:${loc.column + 1}`;
|
|
84
83
|
}
|
|
85
|
-
function isProjectLocalFile(filename, projectRoot) {
|
|
86
|
-
if (!filename) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
const root = normalizeProjectRoot(projectRoot);
|
|
90
|
-
const normalizedFilename = normalizeSlashes(filename);
|
|
91
|
-
if (!root) {
|
|
92
|
-
return !normalizedFilename.startsWith("../") && !normalizedFilename.startsWith("/") && !/^[A-Za-z]:\//.test(normalizedFilename);
|
|
93
|
-
}
|
|
94
|
-
if (normalizedFilename.startsWith(`${root}/`) || normalizedFilename === root) {
|
|
95
|
-
return true;
|
|
96
|
-
}
|
|
97
|
-
const relativePath = computeRelativePath(root, normalizedFilename);
|
|
98
|
-
return !relativePath.startsWith("../");
|
|
99
|
-
}
|
|
100
|
-
function isExternalToProjectRoot(filename, projectRoot) {
|
|
101
|
-
return !isProjectLocalFile(filename, projectRoot);
|
|
102
|
-
}
|
|
103
84
|
|
|
104
85
|
// src/babelInjectComponentSource.ts
|
|
105
|
-
var SOURCE_PROP_LOCAL = "_componentSourceLoc";
|
|
106
|
-
var SOURCE_PROPS_REST = "__reactCodeLocatorProps";
|
|
107
86
|
function isComponentName(name) {
|
|
108
87
|
return /^[A-Z]/.test(name);
|
|
109
88
|
}
|
|
110
|
-
function isCustomComponentTag(name) {
|
|
111
|
-
if (import_core.types.isJSXIdentifier(name)) {
|
|
112
|
-
return isComponentName(name.name);
|
|
113
|
-
}
|
|
114
|
-
if (import_core.types.isJSXMemberExpression(name)) {
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
function isIntrinsicElementTag(name) {
|
|
120
|
-
return import_core.types.isJSXIdentifier(name) && /^[a-z]/.test(name.name);
|
|
121
|
-
}
|
|
122
89
|
function isElementFactoryIdentifier(name) {
|
|
123
90
|
return name === "jsx" || name === "jsxs" || name === "jsxDEV" || name === "_jsx" || name === "_jsxs" || name === "_jsxDEV" || name === "createElement";
|
|
124
91
|
}
|
|
@@ -129,29 +96,6 @@ function isReactElementFactoryCall(pathNode) {
|
|
|
129
96
|
}
|
|
130
97
|
return import_core.types.isMemberExpression(callee) && import_core.types.isIdentifier(callee.object, { name: "React" }) && import_core.types.isIdentifier(callee.property, { name: "createElement" });
|
|
131
98
|
}
|
|
132
|
-
function getRootJsxIdentifierName(name) {
|
|
133
|
-
if (import_core.types.isJSXIdentifier(name)) {
|
|
134
|
-
return name.name;
|
|
135
|
-
}
|
|
136
|
-
if (import_core.types.isJSXMemberExpression(name)) {
|
|
137
|
-
return getRootJsxIdentifierName(name.object);
|
|
138
|
-
}
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
function isStyledModuleImport(binding) {
|
|
142
|
-
if (!binding) {
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
if (!binding.path.isImportSpecifier() && !binding.path.isImportDefaultSpecifier() && !binding.path.isImportNamespaceSpecifier()) {
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
const source = binding.path.parentPath.isImportDeclaration() ? binding.path.parentPath.node.source.value : null;
|
|
149
|
-
if (typeof source !== "string") {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
const normalized = source.replace(/\\/g, "/");
|
|
153
|
-
return normalized === "./styled" || normalized === "../styled" || normalized.endsWith("/styled");
|
|
154
|
-
}
|
|
155
99
|
function isSupportedComponentInit(node) {
|
|
156
100
|
if (!node) {
|
|
157
101
|
return false;
|
|
@@ -167,98 +111,6 @@ function isSupportedComponentInit(node) {
|
|
|
167
111
|
}
|
|
168
112
|
return import_core.types.isMemberExpression(node.callee) && import_core.types.isIdentifier(node.callee.object, { name: "React" }) && import_core.types.isIdentifier(node.callee.property) && (node.callee.property.name === "memo" || node.callee.property.name === "forwardRef");
|
|
169
113
|
}
|
|
170
|
-
function hasSourcePropBinding(pattern) {
|
|
171
|
-
return pattern.properties.some((property) => {
|
|
172
|
-
if (!import_core.types.isObjectProperty(property)) {
|
|
173
|
-
return false;
|
|
174
|
-
}
|
|
175
|
-
return import_core.types.isIdentifier(property.key) && property.key.name === JSX_SOURCE_PROP;
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
function injectSourcePropBinding(pattern) {
|
|
179
|
-
if (hasSourcePropBinding(pattern)) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
const sourceBinding = import_core.types.objectProperty(
|
|
183
|
-
import_core.types.identifier(JSX_SOURCE_PROP),
|
|
184
|
-
import_core.types.identifier(SOURCE_PROP_LOCAL),
|
|
185
|
-
false,
|
|
186
|
-
false
|
|
187
|
-
);
|
|
188
|
-
const restIndex = pattern.properties.findIndex(
|
|
189
|
-
(property) => import_core.types.isRestElement(property)
|
|
190
|
-
);
|
|
191
|
-
if (restIndex === -1) {
|
|
192
|
-
pattern.properties.push(sourceBinding);
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
pattern.properties.splice(restIndex, 0, sourceBinding);
|
|
196
|
-
}
|
|
197
|
-
function injectSourcePropIntoIdentifierParam(node, param) {
|
|
198
|
-
if (!import_core.types.isBlockStatement(node.body)) {
|
|
199
|
-
node.body = import_core.types.blockStatement([import_core.types.returnStatement(node.body)]);
|
|
200
|
-
}
|
|
201
|
-
const alreadyInjected = node.body.body.some(
|
|
202
|
-
(statement) => import_core.types.isVariableDeclaration(statement) && statement.declarations.some(
|
|
203
|
-
(declaration) => import_core.types.isIdentifier(declaration.id) && declaration.id.name === SOURCE_PROPS_REST
|
|
204
|
-
)
|
|
205
|
-
);
|
|
206
|
-
if (alreadyInjected) {
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
node.body.body.unshift(
|
|
210
|
-
import_core.types.variableDeclaration("const", [
|
|
211
|
-
import_core.types.variableDeclarator(
|
|
212
|
-
import_core.types.objectPattern([
|
|
213
|
-
import_core.types.objectProperty(
|
|
214
|
-
import_core.types.identifier(JSX_SOURCE_PROP),
|
|
215
|
-
import_core.types.identifier(SOURCE_PROP_LOCAL),
|
|
216
|
-
false,
|
|
217
|
-
false
|
|
218
|
-
),
|
|
219
|
-
import_core.types.restElement(import_core.types.identifier(SOURCE_PROPS_REST))
|
|
220
|
-
]),
|
|
221
|
-
param
|
|
222
|
-
)
|
|
223
|
-
]),
|
|
224
|
-
import_core.types.expressionStatement(
|
|
225
|
-
import_core.types.assignmentExpression(
|
|
226
|
-
"=",
|
|
227
|
-
import_core.types.identifier(param.name),
|
|
228
|
-
import_core.types.identifier(SOURCE_PROPS_REST)
|
|
229
|
-
)
|
|
230
|
-
)
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
function injectSourcePropIntoFunctionParams(node) {
|
|
234
|
-
const firstParam = node.params[0];
|
|
235
|
-
if (!firstParam) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
if (import_core.types.isObjectPattern(firstParam)) {
|
|
239
|
-
injectSourcePropBinding(firstParam);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
if (import_core.types.isIdentifier(firstParam)) {
|
|
243
|
-
injectSourcePropIntoIdentifierParam(node, firstParam);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
function injectSourcePropIntoExpression(node) {
|
|
247
|
-
if (!node) {
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
if (import_core.types.isFunctionExpression(node) || import_core.types.isArrowFunctionExpression(node)) {
|
|
251
|
-
injectSourcePropIntoFunctionParams(node);
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
if (!import_core.types.isCallExpression(node)) {
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
const firstArg = node.arguments[0];
|
|
258
|
-
if (firstArg && !import_core.types.isSpreadElement(firstArg) && (import_core.types.isFunctionExpression(firstArg) || import_core.types.isArrowFunctionExpression(firstArg))) {
|
|
259
|
-
injectSourcePropIntoFunctionParams(firstArg);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
114
|
function getSourceValue(state, loc, projectRoot) {
|
|
263
115
|
const filename = state.file?.opts?.filename;
|
|
264
116
|
if (!filename || !loc) {
|
|
@@ -275,9 +127,9 @@ function buildAssignment(name, sourceValue) {
|
|
|
275
127
|
)
|
|
276
128
|
);
|
|
277
129
|
}
|
|
278
|
-
function
|
|
130
|
+
function buildElementSourceHelper() {
|
|
279
131
|
return import_core.types.functionDeclaration(
|
|
280
|
-
import_core.types.identifier("
|
|
132
|
+
import_core.types.identifier("_markReactElementSource"),
|
|
281
133
|
[import_core.types.identifier("element"), import_core.types.identifier("source")],
|
|
282
134
|
import_core.types.blockStatement([
|
|
283
135
|
import_core.types.variableDeclaration("const", [
|
|
@@ -341,15 +193,15 @@ function buildIntrinsicSourceHelper() {
|
|
|
341
193
|
])
|
|
342
194
|
);
|
|
343
195
|
}
|
|
344
|
-
function
|
|
196
|
+
function ensureElementSourceHelper(programPath, state) {
|
|
345
197
|
if (state.injectedIntrinsicHelper) {
|
|
346
198
|
return;
|
|
347
199
|
}
|
|
348
200
|
const alreadyExists = programPath.node.body.some(
|
|
349
|
-
(node) => import_core.types.isFunctionDeclaration(node) && import_core.types.isIdentifier(node.id, { name: "
|
|
201
|
+
(node) => import_core.types.isFunctionDeclaration(node) && import_core.types.isIdentifier(node.id, { name: "_markReactElementSource" })
|
|
350
202
|
);
|
|
351
203
|
if (!alreadyExists) {
|
|
352
|
-
programPath.unshiftContainer("body",
|
|
204
|
+
programPath.unshiftContainer("body", buildElementSourceHelper());
|
|
353
205
|
}
|
|
354
206
|
state.injectedIntrinsicHelper = true;
|
|
355
207
|
}
|
|
@@ -359,9 +211,6 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen, project
|
|
|
359
211
|
if (!name || !isComponentName(name) || seen.has(name)) {
|
|
360
212
|
return;
|
|
361
213
|
}
|
|
362
|
-
if (declarationPath.isFunctionDeclaration()) {
|
|
363
|
-
injectSourcePropIntoFunctionParams(declarationPath.node);
|
|
364
|
-
}
|
|
365
214
|
const sourceValue = getSourceValue(
|
|
366
215
|
state,
|
|
367
216
|
declarationPath.node.loc?.start,
|
|
@@ -388,7 +237,6 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen, project
|
|
|
388
237
|
if (!isSupportedComponentInit(declarator.init)) {
|
|
389
238
|
return [];
|
|
390
239
|
}
|
|
391
|
-
injectSourcePropIntoExpression(declarator.init);
|
|
392
240
|
const sourceValue = getSourceValue(
|
|
393
241
|
state,
|
|
394
242
|
declarator.loc?.start ?? declarator.init.loc?.start,
|
|
@@ -422,7 +270,7 @@ function babelInjectComponentSource(options = {}) {
|
|
|
422
270
|
return;
|
|
423
271
|
}
|
|
424
272
|
if (pathNode.parentPath.isCallExpression() && import_core.types.isIdentifier(pathNode.parentPath.node.callee, {
|
|
425
|
-
name: "
|
|
273
|
+
name: "_markReactElementSource"
|
|
426
274
|
})) {
|
|
427
275
|
return;
|
|
428
276
|
}
|
|
@@ -438,9 +286,9 @@ function babelInjectComponentSource(options = {}) {
|
|
|
438
286
|
if (!programPath || !programPath.isProgram()) {
|
|
439
287
|
return;
|
|
440
288
|
}
|
|
441
|
-
|
|
289
|
+
ensureElementSourceHelper(programPath, state);
|
|
442
290
|
pathNode.replaceWith(
|
|
443
|
-
import_core.types.callExpression(import_core.types.identifier("
|
|
291
|
+
import_core.types.callExpression(import_core.types.identifier("_markReactElementSource"), [
|
|
444
292
|
pathNode.node,
|
|
445
293
|
import_core.types.stringLiteral(sourceValue)
|
|
446
294
|
])
|
|
@@ -452,10 +300,7 @@ function babelInjectComponentSource(options = {}) {
|
|
|
452
300
|
if (!injectJsxSource) {
|
|
453
301
|
return;
|
|
454
302
|
}
|
|
455
|
-
if (
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
if (pathNode.parentPath.isCallExpression() && import_core.types.isIdentifier(pathNode.parentPath.node.callee, { name: "_markIntrinsicElementSource" })) {
|
|
303
|
+
if (pathNode.parentPath.isCallExpression() && import_core.types.isIdentifier(pathNode.parentPath.node.callee, { name: "_markReactElementSource" })) {
|
|
459
304
|
return;
|
|
460
305
|
}
|
|
461
306
|
const sourceValue = getSourceValue(
|
|
@@ -470,8 +315,8 @@ function babelInjectComponentSource(options = {}) {
|
|
|
470
315
|
if (!programPath || !programPath.isProgram()) {
|
|
471
316
|
return;
|
|
472
317
|
}
|
|
473
|
-
|
|
474
|
-
const wrappedNode = import_core.types.callExpression(import_core.types.identifier("
|
|
318
|
+
ensureElementSourceHelper(programPath, state);
|
|
319
|
+
const wrappedNode = import_core.types.callExpression(import_core.types.identifier("_markReactElementSource"), [
|
|
475
320
|
pathNode.node,
|
|
476
321
|
import_core.types.stringLiteral(sourceValue)
|
|
477
322
|
]);
|
|
@@ -486,37 +331,6 @@ function babelInjectComponentSource(options = {}) {
|
|
|
486
331
|
pathNode.replaceWith(wrappedNode);
|
|
487
332
|
}
|
|
488
333
|
},
|
|
489
|
-
JSXOpeningElement(pathNode, state) {
|
|
490
|
-
if (!injectJsxSource) {
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
if (!isCustomComponentTag(pathNode.node.name)) {
|
|
494
|
-
return;
|
|
495
|
-
}
|
|
496
|
-
const rootIdentifierName = getRootJsxIdentifierName(pathNode.node.name);
|
|
497
|
-
if (rootIdentifierName && isExternalToProjectRoot(state.file?.opts?.filename, projectRoot) && isStyledModuleImport(pathNode.scope.getBinding(rootIdentifierName))) {
|
|
498
|
-
return;
|
|
499
|
-
}
|
|
500
|
-
const hasSourceProp = pathNode.node.attributes.some(
|
|
501
|
-
(attr) => import_core.types.isJSXAttribute(attr) && import_core.types.isJSXIdentifier(attr.name) && attr.name.name === JSX_SOURCE_PROP
|
|
502
|
-
);
|
|
503
|
-
if (hasSourceProp) {
|
|
504
|
-
return;
|
|
505
|
-
}
|
|
506
|
-
const filename = state.file?.opts?.filename;
|
|
507
|
-
const loc = pathNode.node.loc?.start;
|
|
508
|
-
if (!filename || !loc) {
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
pathNode.node.attributes.push(
|
|
512
|
-
import_core.types.jsxAttribute(
|
|
513
|
-
import_core.types.jsxIdentifier(JSX_SOURCE_PROP),
|
|
514
|
-
import_core.types.stringLiteral(
|
|
515
|
-
getSourceValue(state, loc, projectRoot) ?? `${filename.replace(/\\/g, "/")}:${loc.line}:${loc.column + 1}`
|
|
516
|
-
)
|
|
517
|
-
)
|
|
518
|
-
);
|
|
519
|
-
},
|
|
520
334
|
Program(programPath, state) {
|
|
521
335
|
if (!injectComponentSource) {
|
|
522
336
|
return;
|