react-code-locator 0.1.5 → 0.1.7
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 +63 -25
- package/dist/babel.cjs +27 -11
- package/dist/babel.cjs.map +1 -1
- package/dist/babel.d.cts +1 -1
- package/dist/babel.d.ts +1 -1
- package/dist/babel.js +27 -11
- package/dist/babel.js.map +1 -1
- package/dist/babelInjectComponentSource.cjs +27 -11
- package/dist/babelInjectComponentSource.cjs.map +1 -1
- package/dist/babelInjectComponentSource.d.cts +6 -2
- package/dist/babelInjectComponentSource.d.ts +6 -2
- package/dist/babelInjectComponentSource.js +27 -11
- package/dist/babelInjectComponentSource.js.map +1 -1
- package/dist/client.cjs +20 -5
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +20 -5
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +20 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +20 -5
- package/dist/index.js.map +1 -1
- package/dist/vite.cjs +71 -66
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +2 -2
- package/dist/vite.d.ts +2 -2
- package/dist/vite.js +70 -66
- package/dist/vite.js.map +1 -1
- package/dist/webpackRuntimeEntry.cjs +20 -5
- package/dist/webpackRuntimeEntry.cjs.map +1 -1
- package/dist/webpackRuntimeEntry.js +20 -5
- package/dist/webpackRuntimeEntry.js.map +1 -1
- package/package.json +4 -9
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
개발 중인 React 앱에서 요소를 `Shift + Click`하면 해당 UI와 연결된 소스 위치를 찾는 패키지입니다.
|
|
4
4
|
|
|
5
|
-
- JSX
|
|
5
|
+
- JSX 디버그 정보가 있으면 우선 사용해서 정확한 JSX 위치를 찾습니다.
|
|
6
6
|
- JSX 정보가 없으면 컴포넌트 정의 위치로 fallback 합니다.
|
|
7
7
|
- Vite, Webpack, Babel, 브라우저 런타임을 각각 분리해서 사용할 수 있습니다.
|
|
8
8
|
|
|
@@ -20,19 +20,27 @@ npm i -D /absolute/path/to/react-code-locator
|
|
|
20
20
|
|
|
21
21
|
## 빠른 시작
|
|
22
22
|
|
|
23
|
-
Vite
|
|
23
|
+
Vite 환경에서는 기존 `@vitejs/plugin-react` 설정에 Babel 플러그인을 추가하고, `react-code-locator/vite`는 클라이언트 자동 주입만 맡깁니다.
|
|
24
24
|
|
|
25
25
|
```ts
|
|
26
26
|
import { defineConfig } from "vite";
|
|
27
|
-
import
|
|
27
|
+
import react from "@vitejs/plugin-react";
|
|
28
|
+
import { babelInjectComponentSource, reactComponentJump } from "react-code-locator/vite";
|
|
28
29
|
|
|
29
30
|
export default defineConfig(({ command }) => ({
|
|
30
|
-
plugins:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
plugins: [
|
|
32
|
+
react({
|
|
33
|
+
babel: {
|
|
34
|
+
plugins: [babelInjectComponentSource],
|
|
35
|
+
},
|
|
36
|
+
}),
|
|
37
|
+
...reactComponentJump({
|
|
38
|
+
command,
|
|
39
|
+
locator: {
|
|
40
|
+
triggerKey: "shift",
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
],
|
|
36
44
|
}));
|
|
37
45
|
```
|
|
38
46
|
|
|
@@ -48,21 +56,31 @@ export default defineConfig(({ command }) => ({
|
|
|
48
56
|
|
|
49
57
|
Vite + React 프로젝트용 기본 진입점입니다.
|
|
50
58
|
|
|
51
|
-
- 개발 서버에서만
|
|
59
|
+
- 개발 서버에서만 브라우저 클라이언트를 자동 주입합니다.
|
|
60
|
+
- HTML에는 bare import를 직접 넣지 않고 Vite 가상 모듈을 통해 클라이언트를 로드합니다.
|
|
52
61
|
- 기본값으로 브라우저 클라이언트도 자동 주입합니다.
|
|
62
|
+
- React 플러그인은 직접 만들지 않습니다. 기존 `@vitejs/plugin-react` 설정에 Babel 플러그인을 추가해서 사용해야 합니다.
|
|
53
63
|
|
|
54
64
|
```ts
|
|
55
65
|
import { defineConfig } from "vite";
|
|
56
|
-
import
|
|
66
|
+
import react from "@vitejs/plugin-react";
|
|
67
|
+
import { babelInjectComponentSource, reactComponentJump } from "react-code-locator/vite";
|
|
57
68
|
|
|
58
69
|
export default defineConfig(({ command }) => ({
|
|
59
|
-
plugins:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
plugins: [
|
|
71
|
+
react({
|
|
72
|
+
babel: {
|
|
73
|
+
plugins: [babelInjectComponentSource],
|
|
74
|
+
},
|
|
75
|
+
}),
|
|
76
|
+
...reactComponentJump({
|
|
77
|
+
command,
|
|
78
|
+
locator: {
|
|
79
|
+
triggerKey: "shift",
|
|
80
|
+
},
|
|
81
|
+
injectClient: true,
|
|
82
|
+
}),
|
|
83
|
+
],
|
|
66
84
|
}));
|
|
67
85
|
```
|
|
68
86
|
|
|
@@ -73,6 +91,7 @@ export default defineConfig(({ command }) => ({
|
|
|
73
91
|
- `locator.onLocate(result)`: 위치를 찾았을 때 커스텀 처리
|
|
74
92
|
- `locator.onError(error)`: 위치를 못 찾았을 때 커스텀 처리
|
|
75
93
|
- `injectClient`: `false`로 두면 브라우저 런타임 자동 주입 비활성화
|
|
94
|
+
- `babelInjectComponentSource`: 기존 `@vitejs/plugin-react`의 `babel.plugins`에 추가
|
|
76
95
|
|
|
77
96
|
### `react-code-locator/client`
|
|
78
97
|
|
|
@@ -96,13 +115,21 @@ dispose();
|
|
|
96
115
|
|
|
97
116
|
```ts
|
|
98
117
|
import { defineConfig } from "vite";
|
|
99
|
-
import
|
|
118
|
+
import react from "@vitejs/plugin-react";
|
|
119
|
+
import { babelInjectComponentSource, reactComponentJump } from "react-code-locator/vite";
|
|
100
120
|
|
|
101
121
|
export default defineConfig(({ command }) => ({
|
|
102
|
-
plugins:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
122
|
+
plugins: [
|
|
123
|
+
react({
|
|
124
|
+
babel: {
|
|
125
|
+
plugins: [babelInjectComponentSource],
|
|
126
|
+
},
|
|
127
|
+
}),
|
|
128
|
+
...reactComponentJump({
|
|
129
|
+
command,
|
|
130
|
+
injectClient: false,
|
|
131
|
+
}),
|
|
132
|
+
],
|
|
106
133
|
}));
|
|
107
134
|
```
|
|
108
135
|
|
|
@@ -120,11 +147,12 @@ if (import.meta.env.DEV) {
|
|
|
120
147
|
|
|
121
148
|
Babel 플러그인만 따로 사용할 때 사용합니다.
|
|
122
149
|
|
|
123
|
-
이 플러그인은
|
|
150
|
+
이 플러그인은 기본적으로 한 가지를 주입합니다.
|
|
124
151
|
|
|
125
|
-
- JSX 요소에 `__source`
|
|
126
152
|
- React 컴포넌트 함수/클래스에 `__componentSourceLoc`
|
|
127
153
|
|
|
154
|
+
옵션으로 JSX 요소에도 `__componentSourceLoc`를 주입할 수 있지만 기본값은 `false`입니다.
|
|
155
|
+
|
|
128
156
|
```js
|
|
129
157
|
const { babelInjectComponentSource } = require("react-code-locator/babel");
|
|
130
158
|
|
|
@@ -143,6 +171,16 @@ export default {
|
|
|
143
171
|
};
|
|
144
172
|
```
|
|
145
173
|
|
|
174
|
+
JSX 주입이 꼭 필요하면:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
import { babelInjectComponentSource } from "react-code-locator/babel";
|
|
178
|
+
|
|
179
|
+
export default {
|
|
180
|
+
plugins: [[babelInjectComponentSource, { injectJsxSource: true }]],
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
146
184
|
### `react-code-locator/webpack`
|
|
147
185
|
|
|
148
186
|
Webpack 설정에 Babel 플러그인과 런타임 엔트리를 함께 주입합니다.
|
package/dist/babel.cjs
CHANGED
|
@@ -45,6 +45,21 @@ var SOURCE_PROP = "__componentSourceLoc";
|
|
|
45
45
|
function isComponentName(name) {
|
|
46
46
|
return /^[A-Z]/.test(name);
|
|
47
47
|
}
|
|
48
|
+
function isSupportedComponentInit(node) {
|
|
49
|
+
if (!node) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
if (import_core.types.isArrowFunctionExpression(node) || import_core.types.isFunctionExpression(node)) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (!import_core.types.isCallExpression(node)) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
if (import_core.types.isIdentifier(node.callee) && (node.callee.name === "memo" || node.callee.name === "forwardRef")) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
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");
|
|
62
|
+
}
|
|
48
63
|
function getSourceValue(state, loc) {
|
|
49
64
|
const filename = state.file?.opts?.filename;
|
|
50
65
|
if (!filename || !loc) {
|
|
@@ -86,7 +101,7 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
|
|
|
86
101
|
if (!declarator.init) {
|
|
87
102
|
return [];
|
|
88
103
|
}
|
|
89
|
-
if (!
|
|
104
|
+
if (!isSupportedComponentInit(declarator.init)) {
|
|
90
105
|
return [];
|
|
91
106
|
}
|
|
92
107
|
const sourceValue = getSourceValue(state, declarator.loc?.start ?? declarator.init.loc?.start);
|
|
@@ -100,13 +115,17 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
|
|
|
100
115
|
insertAfterPath.insertAfter(assignments);
|
|
101
116
|
}
|
|
102
117
|
}
|
|
103
|
-
function babelInjectComponentSource() {
|
|
118
|
+
function babelInjectComponentSource(options = {}) {
|
|
119
|
+
const { injectJsxSource = false, injectComponentSource = true } = options;
|
|
104
120
|
return {
|
|
105
121
|
name: "babel-inject-component-source",
|
|
106
122
|
visitor: {
|
|
107
123
|
JSXOpeningElement(pathNode, state) {
|
|
124
|
+
if (!injectJsxSource) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
108
127
|
const hasSourceProp = pathNode.node.attributes.some(
|
|
109
|
-
(attr) => import_core.types.isJSXAttribute(attr) && import_core.types.isJSXIdentifier(attr.name) && attr.name.name ===
|
|
128
|
+
(attr) => import_core.types.isJSXAttribute(attr) && import_core.types.isJSXIdentifier(attr.name) && attr.name.name === SOURCE_PROP
|
|
110
129
|
);
|
|
111
130
|
if (hasSourceProp) {
|
|
112
131
|
return;
|
|
@@ -118,18 +137,15 @@ function babelInjectComponentSource() {
|
|
|
118
137
|
}
|
|
119
138
|
pathNode.node.attributes.push(
|
|
120
139
|
import_core.types.jsxAttribute(
|
|
121
|
-
import_core.types.jsxIdentifier(
|
|
122
|
-
import_core.types.
|
|
123
|
-
import_core.types.objectExpression([
|
|
124
|
-
import_core.types.objectProperty(import_core.types.identifier("fileName"), import_core.types.stringLiteral(filename)),
|
|
125
|
-
import_core.types.objectProperty(import_core.types.identifier("lineNumber"), import_core.types.numericLiteral(loc.line)),
|
|
126
|
-
import_core.types.objectProperty(import_core.types.identifier("columnNumber"), import_core.types.numericLiteral(loc.column + 1))
|
|
127
|
-
])
|
|
128
|
-
)
|
|
140
|
+
import_core.types.jsxIdentifier(SOURCE_PROP),
|
|
141
|
+
import_core.types.stringLiteral(getSourceValue(state, loc) ?? `${filename.replace(/\\/g, "/")}:${loc.line}:${loc.column + 1}`)
|
|
129
142
|
)
|
|
130
143
|
);
|
|
131
144
|
},
|
|
132
145
|
Program(programPath, state) {
|
|
146
|
+
if (!injectComponentSource) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
133
149
|
const seen = /* @__PURE__ */ new Set();
|
|
134
150
|
for (const childPath of programPath.get("body")) {
|
|
135
151
|
if (childPath.isExportNamedDeclaration() || childPath.isExportDefaultDeclaration()) {
|
package/dist/babel.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/babel.ts","../src/babelInjectComponentSource.ts","../src/constants.ts"],"sourcesContent":["export { babelInjectComponentSource } from \"./babelInjectComponentSource\";\n","import path from \"node:path\";\nimport { types as t, type NodePath, type PluginObj } from \"@babel/core\";\nimport { SOURCE_PROP } from \"./constants\";\n\ntype BabelState = {\n file?: {\n opts?: {\n filename?: string;\n };\n };\n};\n\nfunction isComponentName(name: string) {\n return /^[A-Z]/.test(name);\n}\n\nfunction getSourceValue(state: BabelState, loc: { line: number; column: number } | null | undefined) {\n const filename = state.file?.opts?.filename;\n if (!filename || !loc) {\n return null;\n }\n\n const relPath = path.relative(process.cwd(), filename).replace(/\\\\/g, \"/\");\n return `${relPath}:${loc.line}:${loc.column + 1}`;\n}\n\nfunction buildAssignment(name: string, sourceValue: string) {\n return t.expressionStatement(\n t.assignmentExpression(\n \"=\",\n t.memberExpression(t.identifier(name), t.identifier(SOURCE_PROP)),\n t.stringLiteral(sourceValue),\n ),\n );\n}\n\nfunction visitDeclaration(\n declarationPath: NodePath,\n insertAfterPath: NodePath,\n state: BabelState,\n seen: Set<string>,\n) {\n if (declarationPath.isFunctionDeclaration() || declarationPath.isClassDeclaration()) {\n const name = declarationPath.node.id?.name;\n if (!name || !isComponentName(name) || seen.has(name)) {\n return;\n }\n\n const sourceValue = getSourceValue(state, declarationPath.node.loc?.start);\n if (!sourceValue) {\n return;\n }\n\n seen.add(name);\n insertAfterPath.insertAfter(buildAssignment(name, sourceValue));\n return;\n }\n\n if (!declarationPath.isVariableDeclaration()) {\n return;\n }\n\n const assignments = declarationPath.node.declarations.flatMap((declarator) => {\n if (!t.isIdentifier(declarator.id) || !isComponentName(declarator.id.name) || seen.has(declarator.id.name)) {\n return [];\n }\n\n if (!declarator.init) {\n return [];\n }\n\n if (!
|
|
1
|
+
{"version":3,"sources":["../src/babel.ts","../src/babelInjectComponentSource.ts","../src/constants.ts"],"sourcesContent":["export { babelInjectComponentSource } from \"./babelInjectComponentSource\";\nexport type { BabelInjectComponentSourceOptions } from \"./babelInjectComponentSource\";\n","import path from \"node:path\";\nimport { types as t, type NodePath, type PluginObj } from \"@babel/core\";\nimport { SOURCE_PROP } from \"./constants\";\n\nexport type BabelInjectComponentSourceOptions = {\n injectJsxSource?: boolean;\n injectComponentSource?: boolean;\n};\n\ntype BabelState = {\n file?: {\n opts?: {\n filename?: string;\n };\n };\n};\n\nfunction isComponentName(name: string) {\n return /^[A-Z]/.test(name);\n}\n\nfunction isSupportedComponentInit(node: t.Expression | null | undefined): boolean {\n if (!node) {\n return false;\n }\n\n if (t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) {\n return true;\n }\n\n if (!t.isCallExpression(node)) {\n return false;\n }\n\n if (t.isIdentifier(node.callee) && (node.callee.name === \"memo\" || node.callee.name === \"forwardRef\")) {\n return true;\n }\n\n return (\n t.isMemberExpression(node.callee) &&\n t.isIdentifier(node.callee.object, { name: \"React\" }) &&\n t.isIdentifier(node.callee.property) &&\n (node.callee.property.name === \"memo\" || node.callee.property.name === \"forwardRef\")\n );\n}\n\nfunction getSourceValue(state: BabelState, loc: { line: number; column: number } | null | undefined) {\n const filename = state.file?.opts?.filename;\n if (!filename || !loc) {\n return null;\n }\n\n const relPath = path.relative(process.cwd(), filename).replace(/\\\\/g, \"/\");\n return `${relPath}:${loc.line}:${loc.column + 1}`;\n}\n\nfunction buildAssignment(name: string, sourceValue: string) {\n return t.expressionStatement(\n t.assignmentExpression(\n \"=\",\n t.memberExpression(t.identifier(name), t.identifier(SOURCE_PROP)),\n t.stringLiteral(sourceValue),\n ),\n );\n}\n\nfunction visitDeclaration(\n declarationPath: NodePath,\n insertAfterPath: NodePath,\n state: BabelState,\n seen: Set<string>,\n) {\n if (declarationPath.isFunctionDeclaration() || declarationPath.isClassDeclaration()) {\n const name = declarationPath.node.id?.name;\n if (!name || !isComponentName(name) || seen.has(name)) {\n return;\n }\n\n const sourceValue = getSourceValue(state, declarationPath.node.loc?.start);\n if (!sourceValue) {\n return;\n }\n\n seen.add(name);\n insertAfterPath.insertAfter(buildAssignment(name, sourceValue));\n return;\n }\n\n if (!declarationPath.isVariableDeclaration()) {\n return;\n }\n\n const assignments = declarationPath.node.declarations.flatMap((declarator) => {\n if (!t.isIdentifier(declarator.id) || !isComponentName(declarator.id.name) || seen.has(declarator.id.name)) {\n return [];\n }\n\n if (!declarator.init) {\n return [];\n }\n\n if (!isSupportedComponentInit(declarator.init)) {\n return [];\n }\n\n const sourceValue = getSourceValue(state, declarator.loc?.start ?? declarator.init.loc?.start);\n if (!sourceValue) {\n return [];\n }\n\n seen.add(declarator.id.name);\n return [buildAssignment(declarator.id.name, sourceValue)];\n });\n\n if (assignments.length > 0) {\n insertAfterPath.insertAfter(assignments);\n }\n}\n\nexport function babelInjectComponentSource(\n options: BabelInjectComponentSourceOptions = {},\n): PluginObj<BabelState> {\n const { injectJsxSource = false, injectComponentSource = true } = options;\n\n return {\n name: \"babel-inject-component-source\",\n visitor: {\n JSXOpeningElement(pathNode, state) {\n if (!injectJsxSource) {\n return;\n }\n\n const hasSourceProp = pathNode.node.attributes.some(\n (attr) => t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name) && attr.name.name === SOURCE_PROP,\n );\n if (hasSourceProp) {\n return;\n }\n\n const filename = state.file?.opts?.filename;\n const loc = pathNode.node.loc?.start;\n if (!filename || !loc) {\n return;\n }\n\n pathNode.node.attributes.push(\n t.jsxAttribute(\n t.jsxIdentifier(SOURCE_PROP),\n t.stringLiteral(getSourceValue(state, loc) ?? `${filename.replace(/\\\\/g, \"/\")}:${loc.line}:${loc.column + 1}`),\n ),\n );\n },\n Program(programPath, state) {\n if (!injectComponentSource) {\n return;\n }\n\n const seen = new Set<string>();\n\n for (const childPath of programPath.get(\"body\")) {\n if (childPath.isExportNamedDeclaration() || childPath.isExportDefaultDeclaration()) {\n const declarationPath = childPath.get(\"declaration\");\n if (!Array.isArray(declarationPath) && declarationPath.node) {\n visitDeclaration(declarationPath, childPath, state, seen);\n }\n continue;\n }\n\n visitDeclaration(childPath, childPath, state, seen);\n }\n },\n },\n };\n}\n","export const SOURCE_PROP = \"__componentSourceLoc\";\n\n"],"mappings":"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","names":["t","path"]}
|
package/dist/babel.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { babelInjectComponentSource } from './babelInjectComponentSource.cjs';
|
|
1
|
+
export { BabelInjectComponentSourceOptions, babelInjectComponentSource } from './babelInjectComponentSource.cjs';
|
|
2
2
|
import '@babel/core';
|
package/dist/babel.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { babelInjectComponentSource } from './babelInjectComponentSource.js';
|
|
1
|
+
export { BabelInjectComponentSourceOptions, babelInjectComponentSource } from './babelInjectComponentSource.js';
|
|
2
2
|
import '@babel/core';
|
package/dist/babel.js
CHANGED
|
@@ -9,6 +9,21 @@ var SOURCE_PROP = "__componentSourceLoc";
|
|
|
9
9
|
function isComponentName(name) {
|
|
10
10
|
return /^[A-Z]/.test(name);
|
|
11
11
|
}
|
|
12
|
+
function isSupportedComponentInit(node) {
|
|
13
|
+
if (!node) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
if (t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (!t.isCallExpression(node)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (t.isIdentifier(node.callee) && (node.callee.name === "memo" || node.callee.name === "forwardRef")) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return t.isMemberExpression(node.callee) && t.isIdentifier(node.callee.object, { name: "React" }) && t.isIdentifier(node.callee.property) && (node.callee.property.name === "memo" || node.callee.property.name === "forwardRef");
|
|
26
|
+
}
|
|
12
27
|
function getSourceValue(state, loc) {
|
|
13
28
|
const filename = state.file?.opts?.filename;
|
|
14
29
|
if (!filename || !loc) {
|
|
@@ -50,7 +65,7 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
|
|
|
50
65
|
if (!declarator.init) {
|
|
51
66
|
return [];
|
|
52
67
|
}
|
|
53
|
-
if (!
|
|
68
|
+
if (!isSupportedComponentInit(declarator.init)) {
|
|
54
69
|
return [];
|
|
55
70
|
}
|
|
56
71
|
const sourceValue = getSourceValue(state, declarator.loc?.start ?? declarator.init.loc?.start);
|
|
@@ -64,13 +79,17 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
|
|
|
64
79
|
insertAfterPath.insertAfter(assignments);
|
|
65
80
|
}
|
|
66
81
|
}
|
|
67
|
-
function babelInjectComponentSource() {
|
|
82
|
+
function babelInjectComponentSource(options = {}) {
|
|
83
|
+
const { injectJsxSource = false, injectComponentSource = true } = options;
|
|
68
84
|
return {
|
|
69
85
|
name: "babel-inject-component-source",
|
|
70
86
|
visitor: {
|
|
71
87
|
JSXOpeningElement(pathNode, state) {
|
|
88
|
+
if (!injectJsxSource) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
72
91
|
const hasSourceProp = pathNode.node.attributes.some(
|
|
73
|
-
(attr) => t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name) && attr.name.name ===
|
|
92
|
+
(attr) => t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name) && attr.name.name === SOURCE_PROP
|
|
74
93
|
);
|
|
75
94
|
if (hasSourceProp) {
|
|
76
95
|
return;
|
|
@@ -82,18 +101,15 @@ function babelInjectComponentSource() {
|
|
|
82
101
|
}
|
|
83
102
|
pathNode.node.attributes.push(
|
|
84
103
|
t.jsxAttribute(
|
|
85
|
-
t.jsxIdentifier(
|
|
86
|
-
t.
|
|
87
|
-
t.objectExpression([
|
|
88
|
-
t.objectProperty(t.identifier("fileName"), t.stringLiteral(filename)),
|
|
89
|
-
t.objectProperty(t.identifier("lineNumber"), t.numericLiteral(loc.line)),
|
|
90
|
-
t.objectProperty(t.identifier("columnNumber"), t.numericLiteral(loc.column + 1))
|
|
91
|
-
])
|
|
92
|
-
)
|
|
104
|
+
t.jsxIdentifier(SOURCE_PROP),
|
|
105
|
+
t.stringLiteral(getSourceValue(state, loc) ?? `${filename.replace(/\\/g, "/")}:${loc.line}:${loc.column + 1}`)
|
|
93
106
|
)
|
|
94
107
|
);
|
|
95
108
|
},
|
|
96
109
|
Program(programPath, state) {
|
|
110
|
+
if (!injectComponentSource) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
97
113
|
const seen = /* @__PURE__ */ new Set();
|
|
98
114
|
for (const childPath of programPath.get("body")) {
|
|
99
115
|
if (childPath.isExportNamedDeclaration() || childPath.isExportDefaultDeclaration()) {
|
package/dist/babel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/babelInjectComponentSource.ts","../src/constants.ts"],"sourcesContent":["import path from \"node:path\";\nimport { types as t, type NodePath, type PluginObj } from \"@babel/core\";\nimport { SOURCE_PROP } from \"./constants\";\n\ntype BabelState = {\n file?: {\n opts?: {\n filename?: string;\n };\n };\n};\n\nfunction isComponentName(name: string) {\n return /^[A-Z]/.test(name);\n}\n\nfunction getSourceValue(state: BabelState, loc: { line: number; column: number } | null | undefined) {\n const filename = state.file?.opts?.filename;\n if (!filename || !loc) {\n return null;\n }\n\n const relPath = path.relative(process.cwd(), filename).replace(/\\\\/g, \"/\");\n return `${relPath}:${loc.line}:${loc.column + 1}`;\n}\n\nfunction buildAssignment(name: string, sourceValue: string) {\n return t.expressionStatement(\n t.assignmentExpression(\n \"=\",\n t.memberExpression(t.identifier(name), t.identifier(SOURCE_PROP)),\n t.stringLiteral(sourceValue),\n ),\n );\n}\n\nfunction visitDeclaration(\n declarationPath: NodePath,\n insertAfterPath: NodePath,\n state: BabelState,\n seen: Set<string>,\n) {\n if (declarationPath.isFunctionDeclaration() || declarationPath.isClassDeclaration()) {\n const name = declarationPath.node.id?.name;\n if (!name || !isComponentName(name) || seen.has(name)) {\n return;\n }\n\n const sourceValue = getSourceValue(state, declarationPath.node.loc?.start);\n if (!sourceValue) {\n return;\n }\n\n seen.add(name);\n insertAfterPath.insertAfter(buildAssignment(name, sourceValue));\n return;\n }\n\n if (!declarationPath.isVariableDeclaration()) {\n return;\n }\n\n const assignments = declarationPath.node.declarations.flatMap((declarator) => {\n if (!t.isIdentifier(declarator.id) || !isComponentName(declarator.id.name) || seen.has(declarator.id.name)) {\n return [];\n }\n\n if (!declarator.init) {\n return [];\n }\n\n if (!
|
|
1
|
+
{"version":3,"sources":["../src/babelInjectComponentSource.ts","../src/constants.ts"],"sourcesContent":["import path from \"node:path\";\nimport { types as t, type NodePath, type PluginObj } from \"@babel/core\";\nimport { SOURCE_PROP } from \"./constants\";\n\nexport type BabelInjectComponentSourceOptions = {\n injectJsxSource?: boolean;\n injectComponentSource?: boolean;\n};\n\ntype BabelState = {\n file?: {\n opts?: {\n filename?: string;\n };\n };\n};\n\nfunction isComponentName(name: string) {\n return /^[A-Z]/.test(name);\n}\n\nfunction isSupportedComponentInit(node: t.Expression | null | undefined): boolean {\n if (!node) {\n return false;\n }\n\n if (t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) {\n return true;\n }\n\n if (!t.isCallExpression(node)) {\n return false;\n }\n\n if (t.isIdentifier(node.callee) && (node.callee.name === \"memo\" || node.callee.name === \"forwardRef\")) {\n return true;\n }\n\n return (\n t.isMemberExpression(node.callee) &&\n t.isIdentifier(node.callee.object, { name: \"React\" }) &&\n t.isIdentifier(node.callee.property) &&\n (node.callee.property.name === \"memo\" || node.callee.property.name === \"forwardRef\")\n );\n}\n\nfunction getSourceValue(state: BabelState, loc: { line: number; column: number } | null | undefined) {\n const filename = state.file?.opts?.filename;\n if (!filename || !loc) {\n return null;\n }\n\n const relPath = path.relative(process.cwd(), filename).replace(/\\\\/g, \"/\");\n return `${relPath}:${loc.line}:${loc.column + 1}`;\n}\n\nfunction buildAssignment(name: string, sourceValue: string) {\n return t.expressionStatement(\n t.assignmentExpression(\n \"=\",\n t.memberExpression(t.identifier(name), t.identifier(SOURCE_PROP)),\n t.stringLiteral(sourceValue),\n ),\n );\n}\n\nfunction visitDeclaration(\n declarationPath: NodePath,\n insertAfterPath: NodePath,\n state: BabelState,\n seen: Set<string>,\n) {\n if (declarationPath.isFunctionDeclaration() || declarationPath.isClassDeclaration()) {\n const name = declarationPath.node.id?.name;\n if (!name || !isComponentName(name) || seen.has(name)) {\n return;\n }\n\n const sourceValue = getSourceValue(state, declarationPath.node.loc?.start);\n if (!sourceValue) {\n return;\n }\n\n seen.add(name);\n insertAfterPath.insertAfter(buildAssignment(name, sourceValue));\n return;\n }\n\n if (!declarationPath.isVariableDeclaration()) {\n return;\n }\n\n const assignments = declarationPath.node.declarations.flatMap((declarator) => {\n if (!t.isIdentifier(declarator.id) || !isComponentName(declarator.id.name) || seen.has(declarator.id.name)) {\n return [];\n }\n\n if (!declarator.init) {\n return [];\n }\n\n if (!isSupportedComponentInit(declarator.init)) {\n return [];\n }\n\n const sourceValue = getSourceValue(state, declarator.loc?.start ?? declarator.init.loc?.start);\n if (!sourceValue) {\n return [];\n }\n\n seen.add(declarator.id.name);\n return [buildAssignment(declarator.id.name, sourceValue)];\n });\n\n if (assignments.length > 0) {\n insertAfterPath.insertAfter(assignments);\n }\n}\n\nexport function babelInjectComponentSource(\n options: BabelInjectComponentSourceOptions = {},\n): PluginObj<BabelState> {\n const { injectJsxSource = false, injectComponentSource = true } = options;\n\n return {\n name: \"babel-inject-component-source\",\n visitor: {\n JSXOpeningElement(pathNode, state) {\n if (!injectJsxSource) {\n return;\n }\n\n const hasSourceProp = pathNode.node.attributes.some(\n (attr) => t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name) && attr.name.name === SOURCE_PROP,\n );\n if (hasSourceProp) {\n return;\n }\n\n const filename = state.file?.opts?.filename;\n const loc = pathNode.node.loc?.start;\n if (!filename || !loc) {\n return;\n }\n\n pathNode.node.attributes.push(\n t.jsxAttribute(\n t.jsxIdentifier(SOURCE_PROP),\n t.stringLiteral(getSourceValue(state, loc) ?? `${filename.replace(/\\\\/g, \"/\")}:${loc.line}:${loc.column + 1}`),\n ),\n );\n },\n Program(programPath, state) {\n if (!injectComponentSource) {\n return;\n }\n\n const seen = new Set<string>();\n\n for (const childPath of programPath.get(\"body\")) {\n if (childPath.isExportNamedDeclaration() || childPath.isExportDefaultDeclaration()) {\n const declarationPath = childPath.get(\"declaration\");\n if (!Array.isArray(declarationPath) && declarationPath.node) {\n visitDeclaration(declarationPath, childPath, state, seen);\n }\n continue;\n }\n\n visitDeclaration(childPath, childPath, state, seen);\n }\n },\n },\n };\n}\n","export const SOURCE_PROP = \"__componentSourceLoc\";\n\n"],"mappings":"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","names":[]}
|
|
@@ -43,6 +43,21 @@ var SOURCE_PROP = "__componentSourceLoc";
|
|
|
43
43
|
function isComponentName(name) {
|
|
44
44
|
return /^[A-Z]/.test(name);
|
|
45
45
|
}
|
|
46
|
+
function isSupportedComponentInit(node) {
|
|
47
|
+
if (!node) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
if (import_core.types.isArrowFunctionExpression(node) || import_core.types.isFunctionExpression(node)) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (!import_core.types.isCallExpression(node)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (import_core.types.isIdentifier(node.callee) && (node.callee.name === "memo" || node.callee.name === "forwardRef")) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
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");
|
|
60
|
+
}
|
|
46
61
|
function getSourceValue(state, loc) {
|
|
47
62
|
const filename = state.file?.opts?.filename;
|
|
48
63
|
if (!filename || !loc) {
|
|
@@ -84,7 +99,7 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
|
|
|
84
99
|
if (!declarator.init) {
|
|
85
100
|
return [];
|
|
86
101
|
}
|
|
87
|
-
if (!
|
|
102
|
+
if (!isSupportedComponentInit(declarator.init)) {
|
|
88
103
|
return [];
|
|
89
104
|
}
|
|
90
105
|
const sourceValue = getSourceValue(state, declarator.loc?.start ?? declarator.init.loc?.start);
|
|
@@ -98,13 +113,17 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
|
|
|
98
113
|
insertAfterPath.insertAfter(assignments);
|
|
99
114
|
}
|
|
100
115
|
}
|
|
101
|
-
function babelInjectComponentSource() {
|
|
116
|
+
function babelInjectComponentSource(options = {}) {
|
|
117
|
+
const { injectJsxSource = false, injectComponentSource = true } = options;
|
|
102
118
|
return {
|
|
103
119
|
name: "babel-inject-component-source",
|
|
104
120
|
visitor: {
|
|
105
121
|
JSXOpeningElement(pathNode, state) {
|
|
122
|
+
if (!injectJsxSource) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
106
125
|
const hasSourceProp = pathNode.node.attributes.some(
|
|
107
|
-
(attr) => import_core.types.isJSXAttribute(attr) && import_core.types.isJSXIdentifier(attr.name) && attr.name.name ===
|
|
126
|
+
(attr) => import_core.types.isJSXAttribute(attr) && import_core.types.isJSXIdentifier(attr.name) && attr.name.name === SOURCE_PROP
|
|
108
127
|
);
|
|
109
128
|
if (hasSourceProp) {
|
|
110
129
|
return;
|
|
@@ -116,18 +135,15 @@ function babelInjectComponentSource() {
|
|
|
116
135
|
}
|
|
117
136
|
pathNode.node.attributes.push(
|
|
118
137
|
import_core.types.jsxAttribute(
|
|
119
|
-
import_core.types.jsxIdentifier(
|
|
120
|
-
import_core.types.
|
|
121
|
-
import_core.types.objectExpression([
|
|
122
|
-
import_core.types.objectProperty(import_core.types.identifier("fileName"), import_core.types.stringLiteral(filename)),
|
|
123
|
-
import_core.types.objectProperty(import_core.types.identifier("lineNumber"), import_core.types.numericLiteral(loc.line)),
|
|
124
|
-
import_core.types.objectProperty(import_core.types.identifier("columnNumber"), import_core.types.numericLiteral(loc.column + 1))
|
|
125
|
-
])
|
|
126
|
-
)
|
|
138
|
+
import_core.types.jsxIdentifier(SOURCE_PROP),
|
|
139
|
+
import_core.types.stringLiteral(getSourceValue(state, loc) ?? `${filename.replace(/\\/g, "/")}:${loc.line}:${loc.column + 1}`)
|
|
127
140
|
)
|
|
128
141
|
);
|
|
129
142
|
},
|
|
130
143
|
Program(programPath, state) {
|
|
144
|
+
if (!injectComponentSource) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
131
147
|
const seen = /* @__PURE__ */ new Set();
|
|
132
148
|
for (const childPath of programPath.get("body")) {
|
|
133
149
|
if (childPath.isExportNamedDeclaration() || childPath.isExportDefaultDeclaration()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/babelInjectComponentSource.ts","../src/constants.ts"],"sourcesContent":["import path from \"node:path\";\nimport { types as t, type NodePath, type PluginObj } from \"@babel/core\";\nimport { SOURCE_PROP } from \"./constants\";\n\ntype BabelState = {\n file?: {\n opts?: {\n filename?: string;\n };\n };\n};\n\nfunction isComponentName(name: string) {\n return /^[A-Z]/.test(name);\n}\n\nfunction getSourceValue(state: BabelState, loc: { line: number; column: number } | null | undefined) {\n const filename = state.file?.opts?.filename;\n if (!filename || !loc) {\n return null;\n }\n\n const relPath = path.relative(process.cwd(), filename).replace(/\\\\/g, \"/\");\n return `${relPath}:${loc.line}:${loc.column + 1}`;\n}\n\nfunction buildAssignment(name: string, sourceValue: string) {\n return t.expressionStatement(\n t.assignmentExpression(\n \"=\",\n t.memberExpression(t.identifier(name), t.identifier(SOURCE_PROP)),\n t.stringLiteral(sourceValue),\n ),\n );\n}\n\nfunction visitDeclaration(\n declarationPath: NodePath,\n insertAfterPath: NodePath,\n state: BabelState,\n seen: Set<string>,\n) {\n if (declarationPath.isFunctionDeclaration() || declarationPath.isClassDeclaration()) {\n const name = declarationPath.node.id?.name;\n if (!name || !isComponentName(name) || seen.has(name)) {\n return;\n }\n\n const sourceValue = getSourceValue(state, declarationPath.node.loc?.start);\n if (!sourceValue) {\n return;\n }\n\n seen.add(name);\n insertAfterPath.insertAfter(buildAssignment(name, sourceValue));\n return;\n }\n\n if (!declarationPath.isVariableDeclaration()) {\n return;\n }\n\n const assignments = declarationPath.node.declarations.flatMap((declarator) => {\n if (!t.isIdentifier(declarator.id) || !isComponentName(declarator.id.name) || seen.has(declarator.id.name)) {\n return [];\n }\n\n if (!declarator.init) {\n return [];\n }\n\n if (!
|
|
1
|
+
{"version":3,"sources":["../src/babelInjectComponentSource.ts","../src/constants.ts"],"sourcesContent":["import path from \"node:path\";\nimport { types as t, type NodePath, type PluginObj } from \"@babel/core\";\nimport { SOURCE_PROP } from \"./constants\";\n\nexport type BabelInjectComponentSourceOptions = {\n injectJsxSource?: boolean;\n injectComponentSource?: boolean;\n};\n\ntype BabelState = {\n file?: {\n opts?: {\n filename?: string;\n };\n };\n};\n\nfunction isComponentName(name: string) {\n return /^[A-Z]/.test(name);\n}\n\nfunction isSupportedComponentInit(node: t.Expression | null | undefined): boolean {\n if (!node) {\n return false;\n }\n\n if (t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) {\n return true;\n }\n\n if (!t.isCallExpression(node)) {\n return false;\n }\n\n if (t.isIdentifier(node.callee) && (node.callee.name === \"memo\" || node.callee.name === \"forwardRef\")) {\n return true;\n }\n\n return (\n t.isMemberExpression(node.callee) &&\n t.isIdentifier(node.callee.object, { name: \"React\" }) &&\n t.isIdentifier(node.callee.property) &&\n (node.callee.property.name === \"memo\" || node.callee.property.name === \"forwardRef\")\n );\n}\n\nfunction getSourceValue(state: BabelState, loc: { line: number; column: number } | null | undefined) {\n const filename = state.file?.opts?.filename;\n if (!filename || !loc) {\n return null;\n }\n\n const relPath = path.relative(process.cwd(), filename).replace(/\\\\/g, \"/\");\n return `${relPath}:${loc.line}:${loc.column + 1}`;\n}\n\nfunction buildAssignment(name: string, sourceValue: string) {\n return t.expressionStatement(\n t.assignmentExpression(\n \"=\",\n t.memberExpression(t.identifier(name), t.identifier(SOURCE_PROP)),\n t.stringLiteral(sourceValue),\n ),\n );\n}\n\nfunction visitDeclaration(\n declarationPath: NodePath,\n insertAfterPath: NodePath,\n state: BabelState,\n seen: Set<string>,\n) {\n if (declarationPath.isFunctionDeclaration() || declarationPath.isClassDeclaration()) {\n const name = declarationPath.node.id?.name;\n if (!name || !isComponentName(name) || seen.has(name)) {\n return;\n }\n\n const sourceValue = getSourceValue(state, declarationPath.node.loc?.start);\n if (!sourceValue) {\n return;\n }\n\n seen.add(name);\n insertAfterPath.insertAfter(buildAssignment(name, sourceValue));\n return;\n }\n\n if (!declarationPath.isVariableDeclaration()) {\n return;\n }\n\n const assignments = declarationPath.node.declarations.flatMap((declarator) => {\n if (!t.isIdentifier(declarator.id) || !isComponentName(declarator.id.name) || seen.has(declarator.id.name)) {\n return [];\n }\n\n if (!declarator.init) {\n return [];\n }\n\n if (!isSupportedComponentInit(declarator.init)) {\n return [];\n }\n\n const sourceValue = getSourceValue(state, declarator.loc?.start ?? declarator.init.loc?.start);\n if (!sourceValue) {\n return [];\n }\n\n seen.add(declarator.id.name);\n return [buildAssignment(declarator.id.name, sourceValue)];\n });\n\n if (assignments.length > 0) {\n insertAfterPath.insertAfter(assignments);\n }\n}\n\nexport function babelInjectComponentSource(\n options: BabelInjectComponentSourceOptions = {},\n): PluginObj<BabelState> {\n const { injectJsxSource = false, injectComponentSource = true } = options;\n\n return {\n name: \"babel-inject-component-source\",\n visitor: {\n JSXOpeningElement(pathNode, state) {\n if (!injectJsxSource) {\n return;\n }\n\n const hasSourceProp = pathNode.node.attributes.some(\n (attr) => t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name) && attr.name.name === SOURCE_PROP,\n );\n if (hasSourceProp) {\n return;\n }\n\n const filename = state.file?.opts?.filename;\n const loc = pathNode.node.loc?.start;\n if (!filename || !loc) {\n return;\n }\n\n pathNode.node.attributes.push(\n t.jsxAttribute(\n t.jsxIdentifier(SOURCE_PROP),\n t.stringLiteral(getSourceValue(state, loc) ?? `${filename.replace(/\\\\/g, \"/\")}:${loc.line}:${loc.column + 1}`),\n ),\n );\n },\n Program(programPath, state) {\n if (!injectComponentSource) {\n return;\n }\n\n const seen = new Set<string>();\n\n for (const childPath of programPath.get(\"body\")) {\n if (childPath.isExportNamedDeclaration() || childPath.isExportDefaultDeclaration()) {\n const declarationPath = childPath.get(\"declaration\");\n if (!Array.isArray(declarationPath) && declarationPath.node) {\n visitDeclaration(declarationPath, childPath, state, seen);\n }\n continue;\n }\n\n visitDeclaration(childPath, childPath, state, seen);\n }\n },\n },\n };\n}\n","export const SOURCE_PROP = \"__componentSourceLoc\";\n\n"],"mappings":"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","names":["t","path"]}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { PluginObj } from '@babel/core';
|
|
2
2
|
|
|
3
|
+
type BabelInjectComponentSourceOptions = {
|
|
4
|
+
injectJsxSource?: boolean;
|
|
5
|
+
injectComponentSource?: boolean;
|
|
6
|
+
};
|
|
3
7
|
type BabelState = {
|
|
4
8
|
file?: {
|
|
5
9
|
opts?: {
|
|
@@ -7,6 +11,6 @@ type BabelState = {
|
|
|
7
11
|
};
|
|
8
12
|
};
|
|
9
13
|
};
|
|
10
|
-
declare function babelInjectComponentSource(): PluginObj<BabelState>;
|
|
14
|
+
declare function babelInjectComponentSource(options?: BabelInjectComponentSourceOptions): PluginObj<BabelState>;
|
|
11
15
|
|
|
12
|
-
export { babelInjectComponentSource };
|
|
16
|
+
export { type BabelInjectComponentSourceOptions, babelInjectComponentSource };
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { PluginObj } from '@babel/core';
|
|
2
2
|
|
|
3
|
+
type BabelInjectComponentSourceOptions = {
|
|
4
|
+
injectJsxSource?: boolean;
|
|
5
|
+
injectComponentSource?: boolean;
|
|
6
|
+
};
|
|
3
7
|
type BabelState = {
|
|
4
8
|
file?: {
|
|
5
9
|
opts?: {
|
|
@@ -7,6 +11,6 @@ type BabelState = {
|
|
|
7
11
|
};
|
|
8
12
|
};
|
|
9
13
|
};
|
|
10
|
-
declare function babelInjectComponentSource(): PluginObj<BabelState>;
|
|
14
|
+
declare function babelInjectComponentSource(options?: BabelInjectComponentSourceOptions): PluginObj<BabelState>;
|
|
11
15
|
|
|
12
|
-
export { babelInjectComponentSource };
|
|
16
|
+
export { type BabelInjectComponentSourceOptions, babelInjectComponentSource };
|
|
@@ -9,6 +9,21 @@ var SOURCE_PROP = "__componentSourceLoc";
|
|
|
9
9
|
function isComponentName(name) {
|
|
10
10
|
return /^[A-Z]/.test(name);
|
|
11
11
|
}
|
|
12
|
+
function isSupportedComponentInit(node) {
|
|
13
|
+
if (!node) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
if (t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (!t.isCallExpression(node)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (t.isIdentifier(node.callee) && (node.callee.name === "memo" || node.callee.name === "forwardRef")) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return t.isMemberExpression(node.callee) && t.isIdentifier(node.callee.object, { name: "React" }) && t.isIdentifier(node.callee.property) && (node.callee.property.name === "memo" || node.callee.property.name === "forwardRef");
|
|
26
|
+
}
|
|
12
27
|
function getSourceValue(state, loc) {
|
|
13
28
|
const filename = state.file?.opts?.filename;
|
|
14
29
|
if (!filename || !loc) {
|
|
@@ -50,7 +65,7 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
|
|
|
50
65
|
if (!declarator.init) {
|
|
51
66
|
return [];
|
|
52
67
|
}
|
|
53
|
-
if (!
|
|
68
|
+
if (!isSupportedComponentInit(declarator.init)) {
|
|
54
69
|
return [];
|
|
55
70
|
}
|
|
56
71
|
const sourceValue = getSourceValue(state, declarator.loc?.start ?? declarator.init.loc?.start);
|
|
@@ -64,13 +79,17 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen) {
|
|
|
64
79
|
insertAfterPath.insertAfter(assignments);
|
|
65
80
|
}
|
|
66
81
|
}
|
|
67
|
-
function babelInjectComponentSource() {
|
|
82
|
+
function babelInjectComponentSource(options = {}) {
|
|
83
|
+
const { injectJsxSource = false, injectComponentSource = true } = options;
|
|
68
84
|
return {
|
|
69
85
|
name: "babel-inject-component-source",
|
|
70
86
|
visitor: {
|
|
71
87
|
JSXOpeningElement(pathNode, state) {
|
|
88
|
+
if (!injectJsxSource) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
72
91
|
const hasSourceProp = pathNode.node.attributes.some(
|
|
73
|
-
(attr) => t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name) && attr.name.name ===
|
|
92
|
+
(attr) => t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name) && attr.name.name === SOURCE_PROP
|
|
74
93
|
);
|
|
75
94
|
if (hasSourceProp) {
|
|
76
95
|
return;
|
|
@@ -82,18 +101,15 @@ function babelInjectComponentSource() {
|
|
|
82
101
|
}
|
|
83
102
|
pathNode.node.attributes.push(
|
|
84
103
|
t.jsxAttribute(
|
|
85
|
-
t.jsxIdentifier(
|
|
86
|
-
t.
|
|
87
|
-
t.objectExpression([
|
|
88
|
-
t.objectProperty(t.identifier("fileName"), t.stringLiteral(filename)),
|
|
89
|
-
t.objectProperty(t.identifier("lineNumber"), t.numericLiteral(loc.line)),
|
|
90
|
-
t.objectProperty(t.identifier("columnNumber"), t.numericLiteral(loc.column + 1))
|
|
91
|
-
])
|
|
92
|
-
)
|
|
104
|
+
t.jsxIdentifier(SOURCE_PROP),
|
|
105
|
+
t.stringLiteral(getSourceValue(state, loc) ?? `${filename.replace(/\\/g, "/")}:${loc.line}:${loc.column + 1}`)
|
|
93
106
|
)
|
|
94
107
|
);
|
|
95
108
|
},
|
|
96
109
|
Program(programPath, state) {
|
|
110
|
+
if (!injectComponentSource) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
97
113
|
const seen = /* @__PURE__ */ new Set();
|
|
98
114
|
for (const childPath of programPath.get("body")) {
|
|
99
115
|
if (childPath.isExportNamedDeclaration() || childPath.isExportDefaultDeclaration()) {
|