react-reinspect 0.1.2 → 0.1.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/README.md +64 -4
- package/dist/plugin/reinspectAutoDiscoverPlugin.d.ts.map +1 -1
- package/dist/plugin/reinspectAutoDiscoverPlugin.js +85 -8
- package/dist/plugin/reinspectNextAutoDiscoverLoader.d.ts +11 -0
- package/dist/plugin/reinspectNextAutoDiscoverLoader.d.ts.map +1 -0
- package/dist/plugin/reinspectNextAutoDiscoverLoader.js +58 -0
- package/dist/plugin/reinspectNextPlugin.d.ts +32 -0
- package/dist/plugin/reinspectNextPlugin.d.ts.map +1 -0
- package/dist/plugin/reinspectNextPlugin.js +70 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -72,6 +72,19 @@ export default defineConfig({
|
|
|
72
72
|
|
|
73
73
|
Without this plugin, only manually wrapped components (`withReinspect`) are inspectable.
|
|
74
74
|
|
|
75
|
+
Next.js (webpack mode) can use:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
// next.config.ts
|
|
79
|
+
import { withReinspectAutoDiscover } from 'react-reinspect/next-plugin'
|
|
80
|
+
|
|
81
|
+
const nextConfig = {}
|
|
82
|
+
|
|
83
|
+
export default withReinspectAutoDiscover(nextConfig)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
If your Next dev server runs with Turbopack, switch to webpack mode for this transform plugin.
|
|
87
|
+
|
|
75
88
|
|
|
76
89
|
## Example
|
|
77
90
|
|
|
@@ -88,9 +101,12 @@ You are a senior React code agent, your task is to integrate react-reinspect to
|
|
|
88
101
|
Do all of the following in one pass:
|
|
89
102
|
1) Install `react-reinspect` using this repo's package manager.
|
|
90
103
|
2) Turn it on in dev mode ONLY by wiring `ReinspectProvider` at app root.
|
|
91
|
-
3)
|
|
92
|
-
4)
|
|
93
|
-
5)
|
|
104
|
+
3) If this app uses Vite, add `reinspectAutoDiscoverPlugin` from `react-reinspect/vite-plugin` in `vite.config.*`.
|
|
105
|
+
4) If this app uses Next.js (webpack mode), wrap the Next config with `withReinspectAutoDiscover` from `react-reinspect/next-plugin`.
|
|
106
|
+
5) If Next.js is running with Turbopack, either switch dev to webpack for auto-discovery transforms or fall back to manual wrapping (`withReinspect`).
|
|
107
|
+
6) Keep production safe (e.g.: `enabled: import.meta.env.DEV` or however we manage dev/prod in this repo.).
|
|
108
|
+
7) Run validation (build/tests if available) and fix any issues.
|
|
109
|
+
8) Output a concise summary with changed files and how to use it.
|
|
94
110
|
|
|
95
111
|
Use this example as the baseline:
|
|
96
112
|
|
|
@@ -108,6 +124,23 @@ export function AppProviders({ children }: { children: React.ReactNode }) {
|
|
|
108
124
|
return <ReinspectProvider config={reinspectConfig}>{children}</ReinspectProvider>
|
|
109
125
|
}
|
|
110
126
|
|
|
127
|
+
For auto-discovery setup, apply one of these depending on framework:
|
|
128
|
+
|
|
129
|
+
// Vite
|
|
130
|
+
import { defineConfig } from 'vite'
|
|
131
|
+
import react from '@vitejs/plugin-react'
|
|
132
|
+
import { reinspectAutoDiscoverPlugin } from 'react-reinspect/vite-plugin'
|
|
133
|
+
|
|
134
|
+
export default defineConfig({
|
|
135
|
+
plugins: [reinspectAutoDiscoverPlugin(), react()],
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
// Next.js (webpack mode)
|
|
139
|
+
import { withReinspectAutoDiscover } from 'react-reinspect/next-plugin'
|
|
140
|
+
|
|
141
|
+
const nextConfig = {}
|
|
142
|
+
export default withReinspectAutoDiscover(nextConfig)
|
|
143
|
+
|
|
111
144
|
Output format I want from you:
|
|
112
145
|
- What changed (bullet list)
|
|
113
146
|
- Why this is safe in production
|
|
@@ -137,7 +170,34 @@ export function AppProviders({ children }: { children: React.ReactNode }) {
|
|
|
137
170
|
}
|
|
138
171
|
```
|
|
139
172
|
|
|
140
|
-
### 2)
|
|
173
|
+
### 2) Enable auto-discovery transforms (pick your framework)
|
|
174
|
+
|
|
175
|
+
Vite:
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
// vite.config.ts
|
|
179
|
+
import { defineConfig } from 'vite'
|
|
180
|
+
import react from '@vitejs/plugin-react'
|
|
181
|
+
import { reinspectAutoDiscoverPlugin } from 'react-reinspect/vite-plugin'
|
|
182
|
+
|
|
183
|
+
export default defineConfig({
|
|
184
|
+
plugins: [reinspectAutoDiscoverPlugin(), react()],
|
|
185
|
+
})
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Next.js (webpack mode):
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
// next.config.ts
|
|
192
|
+
import { withReinspectAutoDiscover } from 'react-reinspect/next-plugin'
|
|
193
|
+
|
|
194
|
+
const nextConfig = {}
|
|
195
|
+
export default withReinspectAutoDiscover(nextConfig)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
If your Next dev server runs with Turbopack, switch to webpack mode for auto-discovery transforms.
|
|
199
|
+
|
|
200
|
+
### 3) Use it in the browser
|
|
141
201
|
|
|
142
202
|
- Click `Reinspect settings` button.
|
|
143
203
|
- Right-click a wrapped component.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reinspectAutoDiscoverPlugin.d.ts","sourceRoot":"","sources":["../../reinspectAutoDiscoverPlugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,KAAK,iBAAiB,GAAG,aAAa,GAAG,aAAa,CAAA;AAgBtD,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;
|
|
1
|
+
{"version":3,"file":"reinspectAutoDiscoverPlugin.d.ts","sourceRoot":"","sources":["../../reinspectAutoDiscoverPlugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,KAAK,iBAAiB,GAAG,aAAa,GAAG,aAAa,CAAA;AAgBtD,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AAmQD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,iBAAiB,GACvB,2BAA2B,CAwP7B;AAED,wBAAgB,2BAA2B,IAAI,MAAM,CA2CpD"}
|
|
@@ -47,19 +47,92 @@ function unwrapExpression(node) {
|
|
|
47
47
|
}
|
|
48
48
|
return currentNode;
|
|
49
49
|
}
|
|
50
|
-
function
|
|
50
|
+
function isReactCreateElementCall(node) {
|
|
51
51
|
const callee = unwrapExpression(node.callee);
|
|
52
52
|
if (t.isIdentifier(callee)) {
|
|
53
|
-
return callee.name === '
|
|
53
|
+
return callee.name === 'createElement';
|
|
54
54
|
}
|
|
55
55
|
if (t.isMemberExpression(callee) &&
|
|
56
56
|
t.isIdentifier(callee.object) &&
|
|
57
57
|
callee.object.name === 'React' &&
|
|
58
58
|
t.isIdentifier(callee.property)) {
|
|
59
|
-
return callee.property.name === '
|
|
59
|
+
return callee.property.name === 'createElement';
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
function isAstNode(value) {
|
|
64
|
+
return (typeof value === 'object' &&
|
|
65
|
+
value !== null &&
|
|
66
|
+
'type' in value &&
|
|
67
|
+
typeof value.type === 'string');
|
|
68
|
+
}
|
|
69
|
+
function containsRenderableReactNode(node) {
|
|
70
|
+
if (!node) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (t.isJSXElement(node) || t.isJSXFragment(node)) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
if (t.isCallExpression(node) && isReactCreateElementCall(node)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
for (const fieldValue of Object.values(node)) {
|
|
80
|
+
if (Array.isArray(fieldValue)) {
|
|
81
|
+
for (const value of fieldValue) {
|
|
82
|
+
if (isAstNode(value) && containsRenderableReactNode(value)) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (isAstNode(fieldValue) && containsRenderableReactNode(fieldValue)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
function isComponentFunction(node) {
|
|
95
|
+
if (t.isBlockStatement(node.body)) {
|
|
96
|
+
return containsRenderableReactNode(node.body);
|
|
97
|
+
}
|
|
98
|
+
return containsRenderableReactNode(node.body);
|
|
99
|
+
}
|
|
100
|
+
function isMemoForwardRefCallee(callee) {
|
|
101
|
+
const expression = unwrapExpression(callee);
|
|
102
|
+
if (t.isIdentifier(expression)) {
|
|
103
|
+
return expression.name === 'memo' || expression.name === 'forwardRef';
|
|
104
|
+
}
|
|
105
|
+
if (t.isMemberExpression(expression) &&
|
|
106
|
+
t.isIdentifier(expression.object) &&
|
|
107
|
+
expression.object.name === 'React' &&
|
|
108
|
+
t.isIdentifier(expression.property)) {
|
|
109
|
+
return (expression.property.name === 'memo' ||
|
|
110
|
+
expression.property.name === 'forwardRef');
|
|
60
111
|
}
|
|
61
112
|
return false;
|
|
62
113
|
}
|
|
114
|
+
function isMemoForwardRefCall(node) {
|
|
115
|
+
const callee = unwrapExpression(node.callee);
|
|
116
|
+
if (!isMemoForwardRefCallee(callee)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
if (node.arguments.length === 0) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
const firstArgument = node.arguments[0];
|
|
123
|
+
if (!t.isExpression(firstArgument)) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
const componentCandidate = unwrapExpression(firstArgument);
|
|
127
|
+
if (t.isArrowFunctionExpression(componentCandidate) ||
|
|
128
|
+
t.isFunctionExpression(componentCandidate)) {
|
|
129
|
+
return isComponentFunction(componentCandidate);
|
|
130
|
+
}
|
|
131
|
+
if (t.isIdentifier(componentCandidate)) {
|
|
132
|
+
return isPascalCaseIdentifier(componentCandidate.name);
|
|
133
|
+
}
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
63
136
|
function isWrappedInitializer(node) {
|
|
64
137
|
const expression = unwrapExpression(node);
|
|
65
138
|
if (!t.isCallExpression(expression)) {
|
|
@@ -72,7 +145,7 @@ function isWrappedInitializer(node) {
|
|
|
72
145
|
function isComponentInitializer(node) {
|
|
73
146
|
const expression = unwrapExpression(node);
|
|
74
147
|
if (t.isArrowFunctionExpression(expression) || t.isFunctionExpression(expression)) {
|
|
75
|
-
return
|
|
148
|
+
return isComponentFunction(expression);
|
|
76
149
|
}
|
|
77
150
|
if (t.isCallExpression(expression)) {
|
|
78
151
|
return isMemoForwardRefCall(expression);
|
|
@@ -144,7 +217,8 @@ export function transformModuleForAutoDiscover(code, fileId, scope) {
|
|
|
144
217
|
for (let index = 0; index < program.body.length; index += 1) {
|
|
145
218
|
const statement = program.body[index];
|
|
146
219
|
if (t.isFunctionDeclaration(statement) && statement.id) {
|
|
147
|
-
if (isPascalCaseIdentifier(statement.id.name)
|
|
220
|
+
if (isPascalCaseIdentifier(statement.id.name) &&
|
|
221
|
+
isComponentFunction(statement)) {
|
|
148
222
|
program.body.splice(index + 1, 0, createFunctionWrapAssignment(statement.id.name, scope, fallbackName));
|
|
149
223
|
index += 1;
|
|
150
224
|
modified = true;
|
|
@@ -155,7 +229,8 @@ export function transformModuleForAutoDiscover(code, fileId, scope) {
|
|
|
155
229
|
statement.declaration &&
|
|
156
230
|
t.isFunctionDeclaration(statement.declaration) &&
|
|
157
231
|
statement.declaration.id &&
|
|
158
|
-
isPascalCaseIdentifier(statement.declaration.id.name)
|
|
232
|
+
isPascalCaseIdentifier(statement.declaration.id.name) &&
|
|
233
|
+
isComponentFunction(statement.declaration)) {
|
|
159
234
|
program.body.splice(index + 1, 0, createFunctionWrapAssignment(statement.declaration.id.name, scope, fallbackName));
|
|
160
235
|
index += 1;
|
|
161
236
|
modified = true;
|
|
@@ -200,7 +275,9 @@ export function transformModuleForAutoDiscover(code, fileId, scope) {
|
|
|
200
275
|
}
|
|
201
276
|
const declaration = statement.declaration;
|
|
202
277
|
if (t.isFunctionDeclaration(declaration)) {
|
|
203
|
-
if (declaration.id &&
|
|
278
|
+
if (declaration.id &&
|
|
279
|
+
isPascalCaseIdentifier(declaration.id.name) &&
|
|
280
|
+
isComponentFunction(declaration)) {
|
|
204
281
|
const localName = declaration.id.name;
|
|
205
282
|
const replacementStatements = [
|
|
206
283
|
declaration,
|
|
@@ -212,7 +289,7 @@ export function transformModuleForAutoDiscover(code, fileId, scope) {
|
|
|
212
289
|
modified = true;
|
|
213
290
|
continue;
|
|
214
291
|
}
|
|
215
|
-
if (!declaration.id) {
|
|
292
|
+
if (!declaration.id && isComponentFunction(declaration)) {
|
|
216
293
|
const localIdentifier = t.identifier(DEFAULT_EXPORT_LOCAL_IDENTIFIER);
|
|
217
294
|
const wrappedValue = createAutoWrapCall(functionDeclarationToExpression(declaration), undefined, scope, fallbackName);
|
|
218
295
|
const replacementStatements = [
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface ReinspectNextLoaderOptions {
|
|
2
|
+
includeThirdParty?: boolean;
|
|
3
|
+
}
|
|
4
|
+
interface LoaderContextLike {
|
|
5
|
+
resourcePath: string;
|
|
6
|
+
getOptions?: () => ReinspectNextLoaderOptions;
|
|
7
|
+
async?: () => ((error: Error | null, code?: string) => void) | undefined;
|
|
8
|
+
}
|
|
9
|
+
export default function reinspectNextAutoDiscoverLoader(this: LoaderContextLike, sourceCode: string): string | void;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=reinspectNextAutoDiscoverLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reinspectNextAutoDiscoverLoader.d.ts","sourceRoot":"","sources":["../../reinspectNextAutoDiscoverLoader.ts"],"names":[],"mappings":"AAQA,UAAU,0BAA0B;IAClC,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,UAAU,iBAAiB;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,0BAA0B,CAAA;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;CACzE;AA4DD,MAAM,CAAC,OAAO,UAAU,+BAA+B,CACrD,IAAI,EAAE,iBAAiB,EACvB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAyBf"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { shouldSkipThirdPartyModule, transformModuleForAutoDiscover, } from './reinspectAutoDiscoverPlugin';
|
|
3
|
+
const SUPPORTED_FILE_PATTERN = /\.[cm]?[jt]sx?$/;
|
|
4
|
+
function normalizeModuleId(id) {
|
|
5
|
+
return id.split(path.sep).join('/');
|
|
6
|
+
}
|
|
7
|
+
function isSupportedSourceFile(id) {
|
|
8
|
+
if (!SUPPORTED_FILE_PATTERN.test(id)) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if (id.includes('/node_modules/react-reinspect/')) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
function resolveAutoDiscoverScope(normalizedId, includeThirdParty) {
|
|
17
|
+
const isThirdParty = normalizedId.includes('/node_modules/');
|
|
18
|
+
if (!isThirdParty) {
|
|
19
|
+
return 'first-party';
|
|
20
|
+
}
|
|
21
|
+
if (!includeThirdParty || shouldSkipThirdPartyModule(normalizedId)) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return 'third-party';
|
|
25
|
+
}
|
|
26
|
+
function runTransform(sourceCode, normalizedId, options) {
|
|
27
|
+
if (!isSupportedSourceFile(normalizedId)) {
|
|
28
|
+
return sourceCode;
|
|
29
|
+
}
|
|
30
|
+
const includeThirdParty = Boolean(options.includeThirdParty);
|
|
31
|
+
const scope = resolveAutoDiscoverScope(normalizedId, includeThirdParty);
|
|
32
|
+
if (!scope) {
|
|
33
|
+
return sourceCode;
|
|
34
|
+
}
|
|
35
|
+
const transformedResult = transformModuleForAutoDiscover(sourceCode, normalizedId, scope);
|
|
36
|
+
return transformedResult.modified ? transformedResult.code : sourceCode;
|
|
37
|
+
}
|
|
38
|
+
export default function reinspectNextAutoDiscoverLoader(sourceCode) {
|
|
39
|
+
const options = this.getOptions?.() ?? {};
|
|
40
|
+
const normalizedId = normalizeModuleId(this.resourcePath ?? '');
|
|
41
|
+
const callback = this.async?.();
|
|
42
|
+
try {
|
|
43
|
+
const transformedCode = runTransform(sourceCode, normalizedId, options);
|
|
44
|
+
if (callback) {
|
|
45
|
+
callback(null, transformedCode);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
return transformedCode;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const nextError = error instanceof Error ? error : new Error('Failed to transform module');
|
|
52
|
+
if (callback) {
|
|
53
|
+
callback(nextError);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
throw nextError;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface ReinspectNextPluginOptions {
|
|
2
|
+
includeThirdParty?: boolean;
|
|
3
|
+
enableInProduction?: boolean;
|
|
4
|
+
}
|
|
5
|
+
interface NextWebpackOptions {
|
|
6
|
+
dev: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface NextWebpackUseEntry {
|
|
9
|
+
loader?: string;
|
|
10
|
+
options?: {
|
|
11
|
+
includeThirdParty?: boolean;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface NextWebpackRule {
|
|
15
|
+
test?: RegExp;
|
|
16
|
+
enforce?: 'pre' | 'post';
|
|
17
|
+
exclude?: RegExp;
|
|
18
|
+
use?: NextWebpackUseEntry | NextWebpackUseEntry[];
|
|
19
|
+
}
|
|
20
|
+
interface NextWebpackModuleConfig {
|
|
21
|
+
rules?: NextWebpackRule[];
|
|
22
|
+
}
|
|
23
|
+
interface NextWebpackConfig {
|
|
24
|
+
module?: NextWebpackModuleConfig;
|
|
25
|
+
}
|
|
26
|
+
type NextWebpackFunction = (config: NextWebpackConfig, options: NextWebpackOptions) => NextWebpackConfig;
|
|
27
|
+
interface NextConfigLike {
|
|
28
|
+
webpack?: NextWebpackFunction;
|
|
29
|
+
}
|
|
30
|
+
export declare function withReinspectAutoDiscover(nextConfig?: NextConfigLike, pluginOptions?: ReinspectNextPluginOptions): NextConfigLike;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=reinspectNextPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reinspectNextPlugin.d.ts","sourceRoot":"","sources":["../../reinspectNextPlugin.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,0BAA0B;IACzC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,UAAU,kBAAkB;IAC1B,GAAG,EAAE,OAAO,CAAA;CACb;AAED,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE;QACR,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAC5B,CAAA;CACF;AAED,UAAU,eAAe;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,CAAA;CAClD;AAED,UAAU,uBAAuB;IAC/B,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;CAC1B;AAED,UAAU,iBAAiB;IACzB,MAAM,CAAC,EAAE,uBAAuB,CAAA;CACjC;AAED,KAAK,mBAAmB,GAAG,CACzB,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,kBAAkB,KACxB,iBAAiB,CAAA;AAEtB,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,mBAAmB,CAAA;CAC9B;AAqED,wBAAgB,yBAAyB,CACvC,UAAU,GAAE,cAAmB,EAC/B,aAAa,GAAE,0BAA+B,GAC7C,cAAc,CAqBhB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
function resolveNextLoaderPath() {
|
|
3
|
+
const loaderUrl = new URL('./reinspectNextAutoDiscoverLoader.js', import.meta.url);
|
|
4
|
+
if (loaderUrl.protocol === 'file:') {
|
|
5
|
+
return fileURLToPath(loaderUrl);
|
|
6
|
+
}
|
|
7
|
+
return loaderUrl.pathname;
|
|
8
|
+
}
|
|
9
|
+
function hasReinspectLoaderRule(rules) {
|
|
10
|
+
for (const rule of rules) {
|
|
11
|
+
const ruleUse = Array.isArray(rule.use)
|
|
12
|
+
? rule.use
|
|
13
|
+
: rule.use
|
|
14
|
+
? [rule.use]
|
|
15
|
+
: [];
|
|
16
|
+
if (ruleUse.some((entry) => entry.loader === resolveNextLoaderPath())) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
function addReinspectLoaderRule(config, options) {
|
|
23
|
+
const moduleConfig = config.module ?? {};
|
|
24
|
+
const rules = moduleConfig.rules ?? [];
|
|
25
|
+
if (hasReinspectLoaderRule(rules)) {
|
|
26
|
+
config.module = {
|
|
27
|
+
...moduleConfig,
|
|
28
|
+
rules,
|
|
29
|
+
};
|
|
30
|
+
return config;
|
|
31
|
+
}
|
|
32
|
+
const nextLoaderPath = resolveNextLoaderPath();
|
|
33
|
+
const nextRules = [
|
|
34
|
+
{
|
|
35
|
+
test: /\.[cm]?[jt]sx?$/,
|
|
36
|
+
enforce: 'pre',
|
|
37
|
+
exclude: /node_modules/,
|
|
38
|
+
use: [
|
|
39
|
+
{
|
|
40
|
+
loader: nextLoaderPath,
|
|
41
|
+
options: {
|
|
42
|
+
includeThirdParty: Boolean(options.includeThirdParty),
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
...rules,
|
|
48
|
+
];
|
|
49
|
+
config.module = {
|
|
50
|
+
...moduleConfig,
|
|
51
|
+
rules: nextRules,
|
|
52
|
+
};
|
|
53
|
+
return config;
|
|
54
|
+
}
|
|
55
|
+
export function withReinspectAutoDiscover(nextConfig = {}, pluginOptions = {}) {
|
|
56
|
+
const originalWebpack = nextConfig.webpack;
|
|
57
|
+
return {
|
|
58
|
+
...nextConfig,
|
|
59
|
+
webpack(config, options) {
|
|
60
|
+
const resolvedConfig = typeof originalWebpack === 'function'
|
|
61
|
+
? originalWebpack(config, options) ?? config
|
|
62
|
+
: config;
|
|
63
|
+
const shouldEnable = options.dev || Boolean(pluginOptions.enableInProduction);
|
|
64
|
+
if (!shouldEnable) {
|
|
65
|
+
return resolvedConfig;
|
|
66
|
+
}
|
|
67
|
+
return addReinspectLoaderRule(resolvedConfig, pluginOptions);
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-reinspect",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Visual runtime inspector for React components with render counters and style overrides.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
"types": "./dist/plugin/reinspectAutoDiscoverPlugin.d.ts",
|
|
24
24
|
"import": "./dist/plugin/reinspectAutoDiscoverPlugin.js"
|
|
25
25
|
},
|
|
26
|
+
"./next-plugin": {
|
|
27
|
+
"types": "./dist/plugin/reinspectNextPlugin.d.ts",
|
|
28
|
+
"import": "./dist/plugin/reinspectNextPlugin.js"
|
|
29
|
+
},
|
|
26
30
|
"./style.css": "./dist/lib/style.css"
|
|
27
31
|
},
|
|
28
32
|
"files": [
|