next 15.2.0-canary.50 → 15.2.0-canary.52
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.
Potentially problematic release.
This version of next might be problematic. Click here for more details.
- package/dist/bin/next +1 -1
- package/dist/build/index.js +2 -2
- package/dist/build/load-jsconfig.d.ts +1 -0
- package/dist/build/load-jsconfig.js +2 -1
- package/dist/build/load-jsconfig.js.map +1 -1
- package/dist/build/swc/index.js +1 -1
- package/dist/build/webpack-config.d.ts +3 -1
- package/dist/build/webpack-config.js +44 -23
- package/dist/build/webpack-config.js.map +1 -1
- package/dist/client/app-bootstrap.js +1 -1
- package/dist/client/components/errors/attach-hydration-error-state.js +37 -24
- package/dist/client/components/errors/attach-hydration-error-state.js.map +1 -1
- package/dist/client/components/errors/hydration-error-info.js +86 -19
- package/dist/client/components/errors/hydration-error-info.js.map +1 -1
- package/dist/client/components/is-hydration-error.d.ts +1 -0
- package/dist/client/components/is-hydration-error.js +41 -3
- package/dist/client/components/is-hydration-error.js.map +1 -1
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/errors.js +1 -2
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/errors.js.map +1 -1
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.d.ts +1 -56
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.js +4 -240
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.js.map +1 -1
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.js +0 -21
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.js.map +1 -1
- package/dist/client/components/react-dev-overlay/hydration-diff/diff-view.d.ts +54 -0
- package/dist/client/components/react-dev-overlay/hydration-diff/diff-view.js +101 -0
- package/dist/client/components/react-dev-overlay/hydration-diff/diff-view.js.map +1 -0
- package/dist/client/components/react-dev-overlay/internal/container/Errors.js +1 -2
- package/dist/client/components/react-dev-overlay/internal/container/Errors.js.map +1 -1
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.d.ts +2 -56
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.js +28 -227
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.js.map +1 -1
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/index.js +1 -1
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/index.js.map +1 -1
- package/dist/client/components/react-dev-overlay/internal/styles/ComponentStyles.js +3 -1
- package/dist/client/components/react-dev-overlay/internal/styles/ComponentStyles.js.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/compiled/next-server/app-page-experimental.runtime.dev.js +2 -2
- package/dist/compiled/next-server/app-page-experimental.runtime.dev.js.map +1 -1
- package/dist/compiled/next-server/app-page.runtime.dev.js +2 -2
- package/dist/compiled/next-server/app-page.runtime.dev.js.map +1 -1
- package/dist/compiled/next-server/server.runtime.prod.js +6 -6
- package/dist/compiled/next-server/server.runtime.prod.js.map +1 -1
- package/dist/esm/build/index.js +2 -2
- package/dist/esm/build/load-jsconfig.js +2 -1
- package/dist/esm/build/load-jsconfig.js.map +1 -1
- package/dist/esm/build/swc/index.js +1 -1
- package/dist/esm/build/webpack-config.js +44 -23
- package/dist/esm/build/webpack-config.js.map +1 -1
- package/dist/esm/client/app-bootstrap.js +1 -1
- package/dist/esm/client/components/errors/attach-hydration-error-state.js +38 -25
- package/dist/esm/client/components/errors/attach-hydration-error-state.js.map +1 -1
- package/dist/esm/client/components/errors/hydration-error-info.js +87 -20
- package/dist/esm/client/components/errors/hydration-error-info.js.map +1 -1
- package/dist/esm/client/components/is-hydration-error.js +36 -2
- package/dist/esm/client/components/is-hydration-error.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/errors.js +1 -2
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/errors.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.js +3 -287
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.js +0 -21
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/hydration-diff/diff-view.js +132 -0
- package/dist/esm/client/components/react-dev-overlay/hydration-diff/diff-view.js.map +1 -0
- package/dist/esm/client/components/react-dev-overlay/internal/container/Errors.js +1 -2
- package/dist/esm/client/components/react-dev-overlay/internal/container/Errors.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.js +12 -271
- package/dist/esm/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/internal/container/RuntimeError/index.js +1 -1
- package/dist/esm/client/components/react-dev-overlay/internal/container/RuntimeError/index.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/internal/styles/ComponentStyles.js +3 -1
- package/dist/esm/client/components/react-dev-overlay/internal/styles/ComponentStyles.js.map +1 -1
- package/dist/esm/client/index.js +1 -1
- package/dist/esm/lib/metadata/metadata.js +2 -2
- package/dist/esm/lib/metadata/metadata.js.map +1 -1
- package/dist/esm/server/config.js +1 -1
- package/dist/esm/server/dev/hot-reloader-turbopack.js +1 -1
- package/dist/esm/server/dev/hot-reloader-webpack.js +1 -1
- package/dist/esm/server/lib/app-info-log.js +1 -1
- package/dist/esm/server/lib/start-server.js +1 -1
- package/dist/lib/metadata/metadata.js +2 -2
- package/dist/lib/metadata/metadata.js.map +1 -1
- package/dist/server/config.js +1 -1
- package/dist/server/dev/hot-reloader-turbopack.js +1 -1
- package/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/dist/server/lib/app-info-log.js +1 -1
- package/dist/server/lib/start-server.js +1 -1
- package/dist/telemetry/anonymous-meta.js +1 -1
- package/dist/telemetry/events/session-stopped.js +2 -2
- package/dist/telemetry/events/version.js +2 -2
- package/package.json +15 -15
|
@@ -11,35 +11,48 @@ Object.defineProperty(exports, "attachHydrationErrorState", {
|
|
|
11
11
|
const _ishydrationerror = require("../is-hydration-error");
|
|
12
12
|
const _hydrationerrorinfo = require("./hydration-error-info");
|
|
13
13
|
function attachHydrationErrorState(error) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const reactHydrationDiffSegments = (0, _hydrationerrorinfo.getReactHydrationDiffSegments)(error.message);
|
|
15
|
+
let parsedHydrationErrorState = {};
|
|
16
|
+
const isHydrationWarning = (0, _ishydrationerror.testReactHydrationWarning)(error.message);
|
|
17
|
+
// If the reactHydrationDiffSegments exists
|
|
18
|
+
// and the diff (reactHydrationDiffSegments[1]) exists
|
|
19
|
+
// e.g. the hydration diff log error.
|
|
20
|
+
if (reactHydrationDiffSegments && reactHydrationDiffSegments[1]) {
|
|
21
|
+
parsedHydrationErrorState = {
|
|
22
|
+
...error.details,
|
|
23
|
+
..._hydrationerrorinfo.hydrationErrorState,
|
|
24
|
+
warning: _hydrationerrorinfo.hydrationErrorState.warning || [
|
|
25
|
+
(0, _ishydrationerror.getDefaultHydrationErrorMessage)()
|
|
26
|
+
],
|
|
27
|
+
notes: isHydrationWarning ? '' : reactHydrationDiffSegments[0],
|
|
28
|
+
reactOutputComponentDiff: reactHydrationDiffSegments[1]
|
|
29
|
+
};
|
|
30
|
+
// Cache the `reactOutputComponentDiff` into hydrationErrorState.
|
|
31
|
+
// This is only required for now when we still squashed the hydration diff log into hydration error.
|
|
32
|
+
// Once the all error is logged to dev overlay in order, this will go away.
|
|
33
|
+
_hydrationerrorinfo.hydrationErrorState.reactOutputComponentDiff = parsedHydrationErrorState.reactOutputComponentDiff;
|
|
34
|
+
} else {
|
|
35
|
+
// Normal runtime error, where it doesn't contain the hydration diff.
|
|
36
|
+
// If there's any extra information in the error message to display,
|
|
37
|
+
// append it to the error message details property
|
|
38
|
+
if (_hydrationerrorinfo.hydrationErrorState.warning) {
|
|
39
|
+
// The patched console.error found hydration errors logged by React
|
|
40
|
+
// Append the logged warning to the error message
|
|
18
41
|
parsedHydrationErrorState = {
|
|
19
42
|
...error.details,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
(0, _ishydrationerror.getDefaultHydrationErrorMessage)()
|
|
23
|
-
],
|
|
24
|
-
notes: reactHydrationDiffSegments[0],
|
|
25
|
-
reactOutputComponentDiff: reactHydrationDiffSegments[1]
|
|
43
|
+
// It contains the warning, component stack, server and client tag names
|
|
44
|
+
..._hydrationerrorinfo.hydrationErrorState
|
|
26
45
|
};
|
|
27
|
-
} else {
|
|
28
|
-
// If there's any extra information in the error message to display,
|
|
29
|
-
// append it to the error message details property
|
|
30
|
-
if (_hydrationerrorinfo.hydrationErrorState.warning) {
|
|
31
|
-
// The patched console.error found hydration errors logged by React
|
|
32
|
-
// Append the logged warning to the error message
|
|
33
|
-
parsedHydrationErrorState = {
|
|
34
|
-
...error.details,
|
|
35
|
-
// It contains the warning, component stack, server and client tag names
|
|
36
|
-
..._hydrationerrorinfo.hydrationErrorState
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
46
|
}
|
|
40
|
-
|
|
41
|
-
error.
|
|
47
|
+
// Consume the cached hydration diff.
|
|
48
|
+
// This is only required for now when we still squashed the hydration diff log into hydration error.
|
|
49
|
+
// Once the all error is logged to dev overlay in order, this will go away.
|
|
50
|
+
if (_hydrationerrorinfo.hydrationErrorState.reactOutputComponentDiff) {
|
|
51
|
+
parsedHydrationErrorState.reactOutputComponentDiff = _hydrationerrorinfo.hydrationErrorState.reactOutputComponentDiff;
|
|
52
|
+
}
|
|
42
53
|
}
|
|
54
|
+
;
|
|
55
|
+
error.details = parsedHydrationErrorState;
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/client/components/errors/attach-hydration-error-state.ts"],"sourcesContent":["import {\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/client/components/errors/attach-hydration-error-state.ts"],"sourcesContent":["import {\n getDefaultHydrationErrorMessage,\n testReactHydrationWarning,\n} from '../is-hydration-error'\nimport {\n hydrationErrorState,\n getReactHydrationDiffSegments,\n} from './hydration-error-info'\n\nexport function attachHydrationErrorState(error: Error) {\n const reactHydrationDiffSegments = getReactHydrationDiffSegments(\n error.message\n )\n let parsedHydrationErrorState: typeof hydrationErrorState = {}\n const isHydrationWarning = testReactHydrationWarning(error.message)\n // If the reactHydrationDiffSegments exists\n // and the diff (reactHydrationDiffSegments[1]) exists\n // e.g. the hydration diff log error.\n if (reactHydrationDiffSegments && reactHydrationDiffSegments[1]) {\n parsedHydrationErrorState = {\n ...(error as any).details,\n ...hydrationErrorState,\n warning: hydrationErrorState.warning || [\n getDefaultHydrationErrorMessage(),\n ],\n notes: isHydrationWarning ? '' : reactHydrationDiffSegments[0],\n reactOutputComponentDiff: reactHydrationDiffSegments[1],\n }\n // Cache the `reactOutputComponentDiff` into hydrationErrorState.\n // This is only required for now when we still squashed the hydration diff log into hydration error.\n // Once the all error is logged to dev overlay in order, this will go away.\n hydrationErrorState.reactOutputComponentDiff =\n parsedHydrationErrorState.reactOutputComponentDiff\n } else {\n // Normal runtime error, where it doesn't contain the hydration diff.\n\n // If there's any extra information in the error message to display,\n // append it to the error message details property\n if (hydrationErrorState.warning) {\n // The patched console.error found hydration errors logged by React\n // Append the logged warning to the error message\n parsedHydrationErrorState = {\n ...(error as any).details,\n // It contains the warning, component stack, server and client tag names\n ...hydrationErrorState,\n }\n }\n // Consume the cached hydration diff.\n // This is only required for now when we still squashed the hydration diff log into hydration error.\n // Once the all error is logged to dev overlay in order, this will go away.\n if (hydrationErrorState.reactOutputComponentDiff) {\n parsedHydrationErrorState.reactOutputComponentDiff =\n hydrationErrorState.reactOutputComponentDiff\n }\n }\n ;(error as any).details = parsedHydrationErrorState\n}\n"],"names":["attachHydrationErrorState","error","reactHydrationDiffSegments","getReactHydrationDiffSegments","message","parsedHydrationErrorState","isHydrationWarning","testReactHydrationWarning","details","hydrationErrorState","warning","getDefaultHydrationErrorMessage","notes","reactOutputComponentDiff"],"mappings":";;;;+BASgBA;;;eAAAA;;;kCANT;oCAIA;AAEA,SAASA,0BAA0BC,KAAY;IACpD,MAAMC,6BAA6BC,IAAAA,iDAA6B,EAC9DF,MAAMG,OAAO;IAEf,IAAIC,4BAAwD,CAAC;IAC7D,MAAMC,qBAAqBC,IAAAA,2CAAyB,EAACN,MAAMG,OAAO;IAClE,2CAA2C;IAC3C,sDAAsD;IACtD,qCAAqC;IACrC,IAAIF,8BAA8BA,0BAA0B,CAAC,EAAE,EAAE;QAC/DG,4BAA4B;YAC1B,GAAG,AAACJ,MAAcO,OAAO;YACzB,GAAGC,uCAAmB;YACtBC,SAASD,uCAAmB,CAACC,OAAO,IAAI;gBACtCC,IAAAA,iDAA+B;aAChC;YACDC,OAAON,qBAAqB,KAAKJ,0BAA0B,CAAC,EAAE;YAC9DW,0BAA0BX,0BAA0B,CAAC,EAAE;QACzD;QACA,iEAAiE;QACjE,oGAAoG;QACpG,2EAA2E;QAC3EO,uCAAmB,CAACI,wBAAwB,GAC1CR,0BAA0BQ,wBAAwB;IACtD,OAAO;QACL,qEAAqE;QAErE,oEAAoE;QACpE,kDAAkD;QAClD,IAAIJ,uCAAmB,CAACC,OAAO,EAAE;YAC/B,mEAAmE;YACnE,iDAAiD;YACjDL,4BAA4B;gBAC1B,GAAG,AAACJ,MAAcO,OAAO;gBACzB,wEAAwE;gBACxE,GAAGC,uCAAmB;YACxB;QACF;QACA,qCAAqC;QACrC,oGAAoG;QACpG,2EAA2E;QAC3E,IAAIA,uCAAmB,CAACI,wBAAwB,EAAE;YAChDR,0BAA0BQ,wBAAwB,GAChDJ,uCAAmB,CAACI,wBAAwB;QAChD;IACF;;IACEZ,MAAcO,OAAO,GAAGH;AAC5B"}
|
|
@@ -43,7 +43,6 @@ const textAndTagsMismatchWarnings = new Set([
|
|
|
43
43
|
'Warning: Expected server HTML to contain a matching text node for "%s" in <%s>.%s',
|
|
44
44
|
'Warning: Did not expect server HTML to contain the text node "%s" in <%s>.%s'
|
|
45
45
|
]);
|
|
46
|
-
const textMismatchWarning = 'Warning: Text content did not match. Server: "%s" Client: "%s"%s';
|
|
47
46
|
const getHydrationWarningType = (message)=>{
|
|
48
47
|
if (typeof message !== 'string') {
|
|
49
48
|
// TODO: Doesn't make sense to treat no message as a hydration error message.
|
|
@@ -56,17 +55,7 @@ const getHydrationWarningType = (message)=>{
|
|
|
56
55
|
return 'text';
|
|
57
56
|
};
|
|
58
57
|
const isHtmlTagsWarning = (message)=>htmlTagsWarnings.has(message);
|
|
59
|
-
const isTextMismatchWarning = (message)=>textMismatchWarning === message;
|
|
60
58
|
const isTextInTagsMismatchWarning = (msg)=>textAndTagsMismatchWarnings.has(msg);
|
|
61
|
-
const isKnownHydrationWarning = (message)=>{
|
|
62
|
-
if (typeof message !== 'string') {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
// React 18 has the `Warning: ` prefix.
|
|
66
|
-
// React 19 does not.
|
|
67
|
-
const normalizedMessage = message.startsWith('Warning: ') ? message : "Warning: " + message;
|
|
68
|
-
return isHtmlTagsWarning(normalizedMessage) || isTextInTagsMismatchWarning(normalizedMessage) || isTextMismatchWarning(normalizedMessage);
|
|
69
|
-
};
|
|
70
59
|
const getReactHydrationDiffSegments = (msg)=>{
|
|
71
60
|
if (msg) {
|
|
72
61
|
const { message, diff } = (0, _ishydrationerror.getHydrationErrorStackInfo)(msg);
|
|
@@ -81,18 +70,96 @@ function storeHydrationErrorStateFromConsoleArgs() {
|
|
|
81
70
|
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
|
|
82
71
|
args[_key] = arguments[_key];
|
|
83
72
|
}
|
|
84
|
-
|
|
85
|
-
if (
|
|
86
|
-
|
|
73
|
+
let [msg, firstContent, secondContent, ...rest] = args;
|
|
74
|
+
if ((0, _ishydrationerror.testReactHydrationWarning)(msg)) {
|
|
75
|
+
// Some hydration warnings has 4 arguments, some has 3, fallback to the last argument
|
|
76
|
+
// when the 3rd argument is not the component stack but an empty string
|
|
77
|
+
const isReact18 = msg.startsWith('Warning: ');
|
|
78
|
+
// For some warnings, there's only 1 argument for template.
|
|
79
|
+
// The second argument is the diff or component stack.
|
|
80
|
+
if (args.length === 3) {
|
|
81
|
+
secondContent = '';
|
|
82
|
+
}
|
|
83
|
+
const warning = [
|
|
87
84
|
// remove the last %s from the message
|
|
88
85
|
msg,
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
firstContent,
|
|
87
|
+
secondContent
|
|
91
88
|
];
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
const lastArg = (rest[rest.length - 1] || '').trim();
|
|
90
|
+
if (!isReact18) {
|
|
91
|
+
hydrationErrorState.reactOutputComponentDiff = lastArg;
|
|
92
|
+
} else {
|
|
93
|
+
hydrationErrorState.reactOutputComponentDiff = generateHydrationDiffReact18(msg, firstContent, secondContent, lastArg);
|
|
94
|
+
}
|
|
95
|
+
hydrationErrorState.warning = warning;
|
|
96
|
+
hydrationErrorState.serverContent = firstContent;
|
|
97
|
+
hydrationErrorState.clientContent = secondContent;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/*
|
|
101
|
+
* Some hydration errors in React 18 does not have the diff in the error message.
|
|
102
|
+
* Instead it has the error stack trace which is component stack that we can leverage.
|
|
103
|
+
* Will parse the diff from the error stack trace
|
|
104
|
+
* e.g.
|
|
105
|
+
* Warning: Expected server HTML to contain a matching <div> in <p>.
|
|
106
|
+
* at div
|
|
107
|
+
* at p
|
|
108
|
+
* at div
|
|
109
|
+
* at div
|
|
110
|
+
* at Page
|
|
111
|
+
* output:
|
|
112
|
+
* <Page>
|
|
113
|
+
* <div>
|
|
114
|
+
* <p>
|
|
115
|
+
* > <div>
|
|
116
|
+
*
|
|
117
|
+
*/ function generateHydrationDiffReact18(message, firstContent, secondContent, lastArg) {
|
|
118
|
+
const componentStack = lastArg;
|
|
119
|
+
let firstIndex = -1;
|
|
120
|
+
let secondIndex = -1;
|
|
121
|
+
const hydrationWarningType = getHydrationWarningType(message);
|
|
122
|
+
// at div\n at Foo\n at Bar (....)\n -> [div, Foo]
|
|
123
|
+
const components = componentStack.split('\n')// .reverse()
|
|
124
|
+
.map((line, index)=>{
|
|
125
|
+
// `<space>at <component> (<location>)` -> `at <component> (<location>)`
|
|
126
|
+
line = line.trim();
|
|
127
|
+
// extract `<space>at <component>` to `<<component>>`
|
|
128
|
+
// e.g. ` at Foo` -> `<Foo>`
|
|
129
|
+
const [, component, location] = /at (\w+)( \((.*)\))?/.exec(line) || [];
|
|
130
|
+
// If there's no location then it's user-land stack frame
|
|
131
|
+
if (!location) {
|
|
132
|
+
if (component === firstContent && firstIndex === -1) {
|
|
133
|
+
firstIndex = index;
|
|
134
|
+
} else if (component === secondContent && secondIndex === -1) {
|
|
135
|
+
secondIndex = index;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return location ? '' : component;
|
|
139
|
+
}).filter(Boolean).reverse();
|
|
140
|
+
let diff = '';
|
|
141
|
+
for(let i = 0; i < components.length; i++){
|
|
142
|
+
const component = components[i];
|
|
143
|
+
const matchFirstContent = hydrationWarningType === 'tag' && i === components.length - firstIndex - 1;
|
|
144
|
+
const matchSecondContent = hydrationWarningType === 'tag' && i === components.length - secondIndex - 1;
|
|
145
|
+
if (matchFirstContent || matchSecondContent) {
|
|
146
|
+
const spaces = ' '.repeat(Math.max(i * 2 - 2, 0) + 2);
|
|
147
|
+
diff += "> " + spaces + "<" + component + ">\n";
|
|
148
|
+
} else {
|
|
149
|
+
const spaces = ' '.repeat(i * 2 + 2);
|
|
150
|
+
diff += spaces + "<" + component + ">\n";
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (hydrationWarningType === 'text') {
|
|
154
|
+
const spaces = ' '.repeat(components.length * 2);
|
|
155
|
+
diff += "+ " + spaces + '"' + firstContent + '"\n';
|
|
156
|
+
diff += "- " + spaces + '"' + secondContent + '"\n';
|
|
157
|
+
} else if (hydrationWarningType === 'text-in-tag') {
|
|
158
|
+
const spaces = ' '.repeat(components.length * 2);
|
|
159
|
+
diff += "> " + spaces + "<" + secondContent + ">\n";
|
|
160
|
+
diff += "> " + spaces + '"' + firstContent + '"\n';
|
|
95
161
|
}
|
|
162
|
+
return diff;
|
|
96
163
|
}
|
|
97
164
|
|
|
98
165
|
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/client/components/errors/hydration-error-info.ts"],"sourcesContent":["import { getHydrationErrorStackInfo } from '../is-hydration-error'\n\nexport type HydrationErrorState = {\n // Hydration warning template format: <message> <serverContent> <clientContent>\n warning?: [string, string, string]\n componentStack?: string\n serverContent?: string\n clientContent?: string\n // React 19 hydration diff format: <notes> <link> <component diff?>\n notes?: string\n reactOutputComponentDiff?: string\n}\n\ntype NullableText = string | null | undefined\n\nexport const hydrationErrorState: HydrationErrorState = {}\n\n// https://github.com/facebook/react/blob/main/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js used as a reference\nconst htmlTagsWarnings = new Set([\n 'Warning: In HTML, %s cannot be a child of <%s>.%s\\nThis will cause a hydration error.%s',\n 'Warning: In HTML, %s cannot be a descendant of <%s>.\\nThis will cause a hydration error.%s',\n 'Warning: In HTML, text nodes cannot be a child of <%s>.\\nThis will cause a hydration error.',\n \"Warning: In HTML, whitespace text nodes cannot be a child of <%s>. Make sure you don't have any extra whitespace between tags on each line of your source code.\\nThis will cause a hydration error.\",\n 'Warning: Expected server HTML to contain a matching <%s> in <%s>.%s',\n 'Warning: Did not expect server HTML to contain a <%s> in <%s>.%s',\n])\nconst textAndTagsMismatchWarnings = new Set([\n 'Warning: Expected server HTML to contain a matching text node for \"%s\" in <%s>.%s',\n 'Warning: Did not expect server HTML to contain the text node \"%s\" in <%s>.%s',\n])\nconst textMismatchWarning =\n 'Warning: Text content did not match. Server: \"%s\" Client: \"%s\"%s'\n\nexport const getHydrationWarningType = (\n message: NullableText\n): 'tag' | 'text' | 'text-in-tag' => {\n if (typeof message !== 'string') {\n // TODO: Doesn't make sense to treat no message as a hydration error message.\n // We should bail out somewhere earlier.\n return 'text'\n }\n\n const normalizedMessage = message.startsWith('Warning: ')\n ? message\n : `Warning: ${message}`\n\n if (isHtmlTagsWarning(normalizedMessage)) return 'tag'\n if (isTextInTagsMismatchWarning(normalizedMessage)) return 'text-in-tag'\n\n return 'text'\n}\n\nconst isHtmlTagsWarning = (message: string) => htmlTagsWarnings.has(message)\n\nconst isTextMismatchWarning = (message: string) =>\n textMismatchWarning === message\nconst isTextInTagsMismatchWarning = (msg: string) =>\n textAndTagsMismatchWarnings.has(msg)\n\nconst isKnownHydrationWarning = (message: NullableText) => {\n if (typeof message !== 'string') {\n return false\n }\n // React 18 has the `Warning: ` prefix.\n // React 19 does not.\n const normalizedMessage = message.startsWith('Warning: ')\n ? message\n : `Warning: ${message}`\n\n return (\n isHtmlTagsWarning(normalizedMessage) ||\n isTextInTagsMismatchWarning(normalizedMessage) ||\n isTextMismatchWarning(normalizedMessage)\n )\n}\n\nexport const getReactHydrationDiffSegments = (msg: NullableText) => {\n if (msg) {\n const { message, diff } = getHydrationErrorStackInfo(msg)\n if (message) return [message, diff]\n }\n return undefined\n}\n\n/**\n * Patch console.error to capture hydration errors.\n * If any of the knownHydrationWarnings are logged, store the message and component stack.\n * When the hydration runtime error is thrown, the message and component stack are added to the error.\n * This results in a more helpful error message in the error overlay.\n */\n\nexport function storeHydrationErrorStateFromConsoleArgs(...args: any[]) {\n const [msg, serverContent, clientContent, componentStack] = args\n if (isKnownHydrationWarning(msg)) {\n hydrationErrorState.warning = [\n // remove the last %s from the message\n msg,\n serverContent,\n clientContent,\n ]\n hydrationErrorState.componentStack = componentStack\n hydrationErrorState.serverContent = serverContent\n hydrationErrorState.clientContent = clientContent\n }\n}\n"],"names":["getHydrationWarningType","getReactHydrationDiffSegments","hydrationErrorState","storeHydrationErrorStateFromConsoleArgs","htmlTagsWarnings","Set","textAndTagsMismatchWarnings","textMismatchWarning","message","normalizedMessage","startsWith","isHtmlTagsWarning","isTextInTagsMismatchWarning","has","isTextMismatchWarning","msg","isKnownHydrationWarning","diff","getHydrationErrorStackInfo","undefined","args","serverContent","clientContent","componentStack","warning"],"mappings":";;;;;;;;;;;;;;;;;IAiCaA,uBAAuB;eAAvBA;;IA2CAC,6BAA6B;eAA7BA;;IA7DAC,mBAAmB;eAAnBA;;IA4EGC,uCAAuC;eAAvCA;;;kCA3F2B;AAepC,MAAMD,sBAA2C,CAAC;AAEzD,iIAAiI;AACjI,MAAME,mBAAmB,IAAIC,IAAI;IAC/B;IACA;IACA;IACA;IACA;IACA;CACD;AACD,MAAMC,8BAA8B,IAAID,IAAI;IAC1C;IACA;CACD;AACD,MAAME,sBACJ;AAEK,MAAMP,0BAA0B,CACrCQ;IAEA,IAAI,OAAOA,YAAY,UAAU;QAC/B,6EAA6E;QAC7E,wCAAwC;QACxC,OAAO;IACT;IAEA,MAAMC,oBAAoBD,QAAQE,UAAU,CAAC,eACzCF,UACA,AAAC,cAAWA;IAEhB,IAAIG,kBAAkBF,oBAAoB,OAAO;IACjD,IAAIG,4BAA4BH,oBAAoB,OAAO;IAE3D,OAAO;AACT;AAEA,MAAME,oBAAoB,CAACH,UAAoBJ,iBAAiBS,GAAG,CAACL;AAEpE,MAAMM,wBAAwB,CAACN,UAC7BD,wBAAwBC;AAC1B,MAAMI,8BAA8B,CAACG,MACnCT,4BAA4BO,GAAG,CAACE;AAElC,MAAMC,0BAA0B,CAACR;IAC/B,IAAI,OAAOA,YAAY,UAAU;QAC/B,OAAO;IACT;IACA,uCAAuC;IACvC,qBAAqB;IACrB,MAAMC,oBAAoBD,QAAQE,UAAU,CAAC,eACzCF,UACA,AAAC,cAAWA;IAEhB,OACEG,kBAAkBF,sBAClBG,4BAA4BH,sBAC5BK,sBAAsBL;AAE1B;AAEO,MAAMR,gCAAgC,CAACc;IAC5C,IAAIA,KAAK;QACP,MAAM,EAAEP,OAAO,EAAES,IAAI,EAAE,GAAGC,IAAAA,4CAA0B,EAACH;QACrD,IAAIP,SAAS,OAAO;YAACA;YAASS;SAAK;IACrC;IACA,OAAOE;AACT;AASO,SAAShB;IAAwC,IAAA,IAAA,OAAA,UAAA,QAAA,AAAGiB,OAAH,UAAA,OAAA,OAAA,GAAA,OAAA,MAAA;QAAGA,KAAH,QAAA,SAAA,CAAA,KAAc;;IACpE,MAAM,CAACL,KAAKM,eAAeC,eAAeC,eAAe,GAAGH;IAC5D,IAAIJ,wBAAwBD,MAAM;QAChCb,oBAAoBsB,OAAO,GAAG;YAC5B,sCAAsC;YACtCT;YACAM;YACAC;SACD;QACDpB,oBAAoBqB,cAAc,GAAGA;QACrCrB,oBAAoBmB,aAAa,GAAGA;QACpCnB,oBAAoBoB,aAAa,GAAGA;IACtC;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/client/components/errors/hydration-error-info.ts"],"sourcesContent":["import {\n getHydrationErrorStackInfo,\n testReactHydrationWarning,\n} from '../is-hydration-error'\n\nexport type HydrationErrorState = {\n // Hydration warning template format: <message> <serverContent> <clientContent>\n warning?: [string, string, string]\n componentStack?: string\n serverContent?: string\n clientContent?: string\n // React 19 hydration diff format: <notes> <link> <component diff?>\n notes?: string\n reactOutputComponentDiff?: string\n}\n\ntype NullableText = string | null | undefined\n\nexport const hydrationErrorState: HydrationErrorState = {}\n\n// https://github.com/facebook/react/blob/main/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js used as a reference\nconst htmlTagsWarnings = new Set([\n 'Warning: In HTML, %s cannot be a child of <%s>.%s\\nThis will cause a hydration error.%s',\n 'Warning: In HTML, %s cannot be a descendant of <%s>.\\nThis will cause a hydration error.%s',\n 'Warning: In HTML, text nodes cannot be a child of <%s>.\\nThis will cause a hydration error.',\n \"Warning: In HTML, whitespace text nodes cannot be a child of <%s>. Make sure you don't have any extra whitespace between tags on each line of your source code.\\nThis will cause a hydration error.\",\n 'Warning: Expected server HTML to contain a matching <%s> in <%s>.%s',\n 'Warning: Did not expect server HTML to contain a <%s> in <%s>.%s',\n])\nconst textAndTagsMismatchWarnings = new Set([\n 'Warning: Expected server HTML to contain a matching text node for \"%s\" in <%s>.%s',\n 'Warning: Did not expect server HTML to contain the text node \"%s\" in <%s>.%s',\n])\n\nexport const getHydrationWarningType = (\n message: NullableText\n): 'tag' | 'text' | 'text-in-tag' => {\n if (typeof message !== 'string') {\n // TODO: Doesn't make sense to treat no message as a hydration error message.\n // We should bail out somewhere earlier.\n return 'text'\n }\n\n const normalizedMessage = message.startsWith('Warning: ')\n ? message\n : `Warning: ${message}`\n\n if (isHtmlTagsWarning(normalizedMessage)) return 'tag'\n if (isTextInTagsMismatchWarning(normalizedMessage)) return 'text-in-tag'\n\n return 'text'\n}\n\nconst isHtmlTagsWarning = (message: string) => htmlTagsWarnings.has(message)\n\nconst isTextInTagsMismatchWarning = (msg: string) =>\n textAndTagsMismatchWarnings.has(msg)\n\nexport const getReactHydrationDiffSegments = (msg: NullableText) => {\n if (msg) {\n const { message, diff } = getHydrationErrorStackInfo(msg)\n if (message) return [message, diff]\n }\n return undefined\n}\n\n/**\n * Patch console.error to capture hydration errors.\n * If any of the knownHydrationWarnings are logged, store the message and component stack.\n * When the hydration runtime error is thrown, the message and component stack are added to the error.\n * This results in a more helpful error message in the error overlay.\n */\n\nexport function storeHydrationErrorStateFromConsoleArgs(...args: any[]) {\n let [msg, firstContent, secondContent, ...rest] = args\n if (testReactHydrationWarning(msg)) {\n // Some hydration warnings has 4 arguments, some has 3, fallback to the last argument\n // when the 3rd argument is not the component stack but an empty string\n const isReact18 = msg.startsWith('Warning: ')\n\n // For some warnings, there's only 1 argument for template.\n // The second argument is the diff or component stack.\n if (args.length === 3) {\n secondContent = ''\n }\n\n const warning: [string, string, string] = [\n // remove the last %s from the message\n msg,\n firstContent,\n secondContent,\n ]\n\n const lastArg = (rest[rest.length - 1] || '').trim()\n if (!isReact18) {\n hydrationErrorState.reactOutputComponentDiff = lastArg\n } else {\n hydrationErrorState.reactOutputComponentDiff =\n generateHydrationDiffReact18(msg, firstContent, secondContent, lastArg)\n }\n\n hydrationErrorState.warning = warning\n hydrationErrorState.serverContent = firstContent\n hydrationErrorState.clientContent = secondContent\n }\n}\n\n/*\n * Some hydration errors in React 18 does not have the diff in the error message.\n * Instead it has the error stack trace which is component stack that we can leverage.\n * Will parse the diff from the error stack trace\n * e.g.\n * Warning: Expected server HTML to contain a matching <div> in <p>.\n * at div\n * at p\n * at div\n * at div\n * at Page\n * output:\n * <Page>\n * <div>\n * <p>\n * > <div>\n *\n */\nfunction generateHydrationDiffReact18(\n message: string,\n firstContent: string,\n secondContent: string,\n lastArg: string\n) {\n const componentStack = lastArg\n let firstIndex = -1\n let secondIndex = -1\n const hydrationWarningType = getHydrationWarningType(message)\n\n // at div\\n at Foo\\n at Bar (....)\\n -> [div, Foo]\n const components = componentStack\n .split('\\n')\n // .reverse()\n .map((line: string, index: number) => {\n // `<space>at <component> (<location>)` -> `at <component> (<location>)`\n line = line.trim()\n // extract `<space>at <component>` to `<<component>>`\n // e.g. ` at Foo` -> `<Foo>`\n const [, component, location] = /at (\\w+)( \\((.*)\\))?/.exec(line) || []\n // If there's no location then it's user-land stack frame\n if (!location) {\n if (component === firstContent && firstIndex === -1) {\n firstIndex = index\n } else if (component === secondContent && secondIndex === -1) {\n secondIndex = index\n }\n }\n return location ? '' : component\n })\n .filter(Boolean)\n .reverse()\n\n let diff = ''\n for (let i = 0; i < components.length; i++) {\n const component = components[i]\n const matchFirstContent =\n hydrationWarningType === 'tag' && i === components.length - firstIndex - 1\n const matchSecondContent =\n hydrationWarningType === 'tag' &&\n i === components.length - secondIndex - 1\n if (matchFirstContent || matchSecondContent) {\n const spaces = ' '.repeat(Math.max(i * 2 - 2, 0) + 2)\n diff += `> ${spaces}<${component}>\\n`\n } else {\n const spaces = ' '.repeat(i * 2 + 2)\n diff += `${spaces}<${component}>\\n`\n }\n }\n if (hydrationWarningType === 'text') {\n const spaces = ' '.repeat(components.length * 2)\n diff += `+ ${spaces}\"${firstContent}\"\\n`\n diff += `- ${spaces}\"${secondContent}\"\\n`\n } else if (hydrationWarningType === 'text-in-tag') {\n const spaces = ' '.repeat(components.length * 2)\n diff += `> ${spaces}<${secondContent}>\\n`\n diff += `> ${spaces}\"${firstContent}\"\\n`\n }\n return diff\n}\n"],"names":["getHydrationWarningType","getReactHydrationDiffSegments","hydrationErrorState","storeHydrationErrorStateFromConsoleArgs","htmlTagsWarnings","Set","textAndTagsMismatchWarnings","message","normalizedMessage","startsWith","isHtmlTagsWarning","isTextInTagsMismatchWarning","has","msg","diff","getHydrationErrorStackInfo","undefined","args","firstContent","secondContent","rest","testReactHydrationWarning","isReact18","length","warning","lastArg","trim","reactOutputComponentDiff","generateHydrationDiffReact18","serverContent","clientContent","componentStack","firstIndex","secondIndex","hydrationWarningType","components","split","map","line","index","component","location","exec","filter","Boolean","reverse","i","matchFirstContent","matchSecondContent","spaces","repeat","Math","max"],"mappings":";;;;;;;;;;;;;;;;;IAkCaA,uBAAuB;eAAvBA;;IAwBAC,6BAA6B;eAA7BA;;IAxCAC,mBAAmB;eAAnBA;;IAuDGC,uCAAuC;eAAvCA;;;kCAtET;AAeA,MAAMD,sBAA2C,CAAC;AAEzD,iIAAiI;AACjI,MAAME,mBAAmB,IAAIC,IAAI;IAC/B;IACA;IACA;IACA;IACA;IACA;CACD;AACD,MAAMC,8BAA8B,IAAID,IAAI;IAC1C;IACA;CACD;AAEM,MAAML,0BAA0B,CACrCO;IAEA,IAAI,OAAOA,YAAY,UAAU;QAC/B,6EAA6E;QAC7E,wCAAwC;QACxC,OAAO;IACT;IAEA,MAAMC,oBAAoBD,QAAQE,UAAU,CAAC,eACzCF,UACA,AAAC,cAAWA;IAEhB,IAAIG,kBAAkBF,oBAAoB,OAAO;IACjD,IAAIG,4BAA4BH,oBAAoB,OAAO;IAE3D,OAAO;AACT;AAEA,MAAME,oBAAoB,CAACH,UAAoBH,iBAAiBQ,GAAG,CAACL;AAEpE,MAAMI,8BAA8B,CAACE,MACnCP,4BAA4BM,GAAG,CAACC;AAE3B,MAAMZ,gCAAgC,CAACY;IAC5C,IAAIA,KAAK;QACP,MAAM,EAAEN,OAAO,EAAEO,IAAI,EAAE,GAAGC,IAAAA,4CAA0B,EAACF;QACrD,IAAIN,SAAS,OAAO;YAACA;YAASO;SAAK;IACrC;IACA,OAAOE;AACT;AASO,SAASb;IAAwC,IAAA,IAAA,OAAA,UAAA,QAAA,AAAGc,OAAH,UAAA,OAAA,OAAA,GAAA,OAAA,MAAA;QAAGA,KAAH,QAAA,SAAA,CAAA,KAAc;;IACpE,IAAI,CAACJ,KAAKK,cAAcC,eAAe,GAAGC,KAAK,GAAGH;IAClD,IAAII,IAAAA,2CAAyB,EAACR,MAAM;QAClC,qFAAqF;QACrF,uEAAuE;QACvE,MAAMS,YAAYT,IAAIJ,UAAU,CAAC;QAEjC,2DAA2D;QAC3D,sDAAsD;QACtD,IAAIQ,KAAKM,MAAM,KAAK,GAAG;YACrBJ,gBAAgB;QAClB;QAEA,MAAMK,UAAoC;YACxC,sCAAsC;YACtCX;YACAK;YACAC;SACD;QAED,MAAMM,UAAU,AAACL,CAAAA,IAAI,CAACA,KAAKG,MAAM,GAAG,EAAE,IAAI,EAAC,EAAGG,IAAI;QAClD,IAAI,CAACJ,WAAW;YACdpB,oBAAoByB,wBAAwB,GAAGF;QACjD,OAAO;YACLvB,oBAAoByB,wBAAwB,GAC1CC,6BAA6Bf,KAAKK,cAAcC,eAAeM;QACnE;QAEAvB,oBAAoBsB,OAAO,GAAGA;QAC9BtB,oBAAoB2B,aAAa,GAAGX;QACpChB,oBAAoB4B,aAAa,GAAGX;IACtC;AACF;AAEA;;;;;;;;;;;;;;;;;CAiBC,GACD,SAASS,6BACPrB,OAAe,EACfW,YAAoB,EACpBC,aAAqB,EACrBM,OAAe;IAEf,MAAMM,iBAAiBN;IACvB,IAAIO,aAAa,CAAC;IAClB,IAAIC,cAAc,CAAC;IACnB,MAAMC,uBAAuBlC,wBAAwBO;IAErD,kDAAkD;IAClD,MAAM4B,aAAaJ,eAChBK,KAAK,CAAC,KACP,aAAa;KACZC,GAAG,CAAC,CAACC,MAAcC;QAClB,wEAAwE;QACxED,OAAOA,KAAKZ,IAAI;QAChB,qDAAqD;QACrD,6BAA6B;QAC7B,MAAM,GAAGc,WAAWC,SAAS,GAAG,uBAAuBC,IAAI,CAACJ,SAAS,EAAE;QACvE,yDAAyD;QACzD,IAAI,CAACG,UAAU;YACb,IAAID,cAActB,gBAAgBc,eAAe,CAAC,GAAG;gBACnDA,aAAaO;YACf,OAAO,IAAIC,cAAcrB,iBAAiBc,gBAAgB,CAAC,GAAG;gBAC5DA,cAAcM;YAChB;QACF;QACA,OAAOE,WAAW,KAAKD;IACzB,GACCG,MAAM,CAACC,SACPC,OAAO;IAEV,IAAI/B,OAAO;IACX,IAAK,IAAIgC,IAAI,GAAGA,IAAIX,WAAWZ,MAAM,EAAEuB,IAAK;QAC1C,MAAMN,YAAYL,UAAU,CAACW,EAAE;QAC/B,MAAMC,oBACJb,yBAAyB,SAASY,MAAMX,WAAWZ,MAAM,GAAGS,aAAa;QAC3E,MAAMgB,qBACJd,yBAAyB,SACzBY,MAAMX,WAAWZ,MAAM,GAAGU,cAAc;QAC1C,IAAIc,qBAAqBC,oBAAoB;YAC3C,MAAMC,SAAS,IAAIC,MAAM,CAACC,KAAKC,GAAG,CAACN,IAAI,IAAI,GAAG,KAAK;YACnDhC,QAAQ,AAAC,OAAImC,SAAO,MAAGT,YAAU;QACnC,OAAO;YACL,MAAMS,SAAS,IAAIC,MAAM,CAACJ,IAAI,IAAI;YAClChC,QAAQ,AAAGmC,SAAO,MAAGT,YAAU;QACjC;IACF;IACA,IAAIN,yBAAyB,QAAQ;QACnC,MAAMe,SAAS,IAAIC,MAAM,CAACf,WAAWZ,MAAM,GAAG;QAC9CT,QAAQ,AAAC,OAAImC,SAAO,MAAG/B,eAAa;QACpCJ,QAAQ,AAAC,OAAImC,SAAO,MAAG9B,gBAAc;IACvC,OAAO,IAAIe,yBAAyB,eAAe;QACjD,MAAMe,SAAS,IAAIC,MAAM,CAACf,WAAWZ,MAAM,GAAG;QAC9CT,QAAQ,AAAC,OAAImC,SAAO,MAAG9B,gBAAc;QACrCL,QAAQ,AAAC,SAAMmC,SAAO,MAAG/B,eAAa;IACxC;IACA,OAAOJ;AACT"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const getDefaultHydrationErrorMessage: () => string;
|
|
2
2
|
export declare function isHydrationError(error: unknown): boolean;
|
|
3
3
|
export declare function isReactHydrationErrorMessage(msg: string): boolean;
|
|
4
|
+
export declare function testReactHydrationWarning(msg: string): boolean;
|
|
4
5
|
export declare function getHydrationErrorStackInfo(rawMessage: string): {
|
|
5
6
|
message: string | null;
|
|
6
7
|
link?: string;
|
|
@@ -6,7 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
getDefaultHydrationErrorMessage: null,
|
|
7
7
|
getHydrationErrorStackInfo: null,
|
|
8
8
|
isHydrationError: null,
|
|
9
|
-
isReactHydrationErrorMessage: null
|
|
9
|
+
isReactHydrationErrorMessage: null,
|
|
10
|
+
testReactHydrationWarning: null
|
|
10
11
|
});
|
|
11
12
|
function _export(target, all) {
|
|
12
13
|
for(var name in all)Object.defineProperty(target, name, {
|
|
@@ -26,6 +27,9 @@ _export(exports, {
|
|
|
26
27
|
},
|
|
27
28
|
isReactHydrationErrorMessage: function() {
|
|
28
29
|
return isReactHydrationErrorMessage;
|
|
30
|
+
},
|
|
31
|
+
testReactHydrationWarning: function() {
|
|
32
|
+
return testReactHydrationWarning;
|
|
29
33
|
}
|
|
30
34
|
});
|
|
31
35
|
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
|
|
@@ -46,11 +50,45 @@ function isHydrationError(error) {
|
|
|
46
50
|
function isReactHydrationErrorMessage(msg) {
|
|
47
51
|
return reactHydrationStartMessages.some((prefix)=>msg.startsWith(prefix));
|
|
48
52
|
}
|
|
53
|
+
const hydrationWarningRegexes = [
|
|
54
|
+
/^In HTML, (.+?) cannot be a child of <(.+?)>\.(.*)\nThis will cause a hydration error\.(.*)/,
|
|
55
|
+
/^In HTML, (.+?) cannot be a descendant of <(.+?)>\.\nThis will cause a hydration error\.(.*)/,
|
|
56
|
+
/^In HTML, text nodes cannot be a child of <(.+?)>\.\nThis will cause a hydration error\./,
|
|
57
|
+
/^In HTML, whitespace text nodes cannot be a child of <(.+?)>\. Make sure you don't have any extra whitespace between tags on each line of your source code\.\nThis will cause a hydration error\./,
|
|
58
|
+
/^Expected server HTML to contain a matching <(.+?)> in <(.+?)>\.(.*)/,
|
|
59
|
+
/^Did not expect server HTML to contain a <(.+?)> in <(.+?)>\.(.*)/,
|
|
60
|
+
/^Expected server HTML to contain a matching text node for "(.+?)" in <(.+?)>\.(.*)/,
|
|
61
|
+
/^Did not expect server HTML to contain the text node "(.+?)" in <(.+?)>\.(.*)/,
|
|
62
|
+
/^Text content did not match\. Server: "(.+?)" Client: "(.+?)"(.*)/
|
|
63
|
+
];
|
|
64
|
+
function testReactHydrationWarning(msg) {
|
|
65
|
+
if (typeof msg !== 'string' || !msg) return false;
|
|
66
|
+
// React 18 has the `Warning: ` prefix.
|
|
67
|
+
// React 19 does not.
|
|
68
|
+
if (msg.startsWith('Warning: ')) {
|
|
69
|
+
msg = msg.slice('Warning: '.length);
|
|
70
|
+
}
|
|
71
|
+
return hydrationWarningRegexes.some((regex)=>regex.test(msg));
|
|
72
|
+
}
|
|
49
73
|
function getHydrationErrorStackInfo(rawMessage) {
|
|
50
74
|
rawMessage = rawMessage.replace(/^Error: /, '');
|
|
51
|
-
|
|
75
|
+
rawMessage = rawMessage.replace('Warning: ', '');
|
|
76
|
+
const isReactHydrationWarning = testReactHydrationWarning(rawMessage);
|
|
77
|
+
if (!isReactHydrationErrorMessage(rawMessage) && !isReactHydrationWarning) {
|
|
52
78
|
return {
|
|
53
|
-
message: null
|
|
79
|
+
message: null,
|
|
80
|
+
link: '',
|
|
81
|
+
stack: rawMessage,
|
|
82
|
+
diff: ''
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (isReactHydrationWarning) {
|
|
86
|
+
const [message, diffLog] = rawMessage.split('\n\n');
|
|
87
|
+
return {
|
|
88
|
+
message: message.trim(),
|
|
89
|
+
link: reactHydrationErrorDocLink,
|
|
90
|
+
stack: '',
|
|
91
|
+
diff: (diffLog || '').trim()
|
|
54
92
|
};
|
|
55
93
|
}
|
|
56
94
|
const firstLineBreak = rawMessage.indexOf('\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/components/is-hydration-error.ts"],"sourcesContent":["import isError from '../../lib/is-error'\n\nconst hydrationErrorRegex =\n /hydration failed|while hydrating|content does not match|did not match|HTML didn't match/i\n\nconst reactUnifiedMismatchWarning = `Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:`\n\nconst reactHydrationStartMessages = [\n reactUnifiedMismatchWarning,\n `A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:`,\n]\n\nconst reactHydrationErrorDocLink = 'https://react.dev/link/hydration-mismatch'\n\nexport const getDefaultHydrationErrorMessage = () => {\n return reactUnifiedMismatchWarning\n}\n\nexport function isHydrationError(error: unknown): boolean {\n return isError(error) && hydrationErrorRegex.test(error.message)\n}\n\nexport function isReactHydrationErrorMessage(msg: string): boolean {\n return reactHydrationStartMessages.some((prefix) => msg.startsWith(prefix))\n}\n\nexport function getHydrationErrorStackInfo(rawMessage: string): {\n message: string | null\n link?: string\n stack?: string\n diff?: string\n} {\n rawMessage = rawMessage.replace(/^Error: /, '')\n if (!isReactHydrationErrorMessage(rawMessage)) {\n return {
|
|
1
|
+
{"version":3,"sources":["../../../src/client/components/is-hydration-error.ts"],"sourcesContent":["import isError from '../../lib/is-error'\n\nconst hydrationErrorRegex =\n /hydration failed|while hydrating|content does not match|did not match|HTML didn't match/i\n\nconst reactUnifiedMismatchWarning = `Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:`\n\nconst reactHydrationStartMessages = [\n reactUnifiedMismatchWarning,\n `A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:`,\n]\n\nconst reactHydrationErrorDocLink = 'https://react.dev/link/hydration-mismatch'\n\nexport const getDefaultHydrationErrorMessage = () => {\n return reactUnifiedMismatchWarning\n}\n\nexport function isHydrationError(error: unknown): boolean {\n return isError(error) && hydrationErrorRegex.test(error.message)\n}\n\nexport function isReactHydrationErrorMessage(msg: string): boolean {\n return reactHydrationStartMessages.some((prefix) => msg.startsWith(prefix))\n}\n\nconst hydrationWarningRegexes = [\n /^In HTML, (.+?) cannot be a child of <(.+?)>\\.(.*)\\nThis will cause a hydration error\\.(.*)/,\n /^In HTML, (.+?) cannot be a descendant of <(.+?)>\\.\\nThis will cause a hydration error\\.(.*)/,\n /^In HTML, text nodes cannot be a child of <(.+?)>\\.\\nThis will cause a hydration error\\./,\n /^In HTML, whitespace text nodes cannot be a child of <(.+?)>\\. Make sure you don't have any extra whitespace between tags on each line of your source code\\.\\nThis will cause a hydration error\\./,\n /^Expected server HTML to contain a matching <(.+?)> in <(.+?)>\\.(.*)/,\n /^Did not expect server HTML to contain a <(.+?)> in <(.+?)>\\.(.*)/,\n /^Expected server HTML to contain a matching text node for \"(.+?)\" in <(.+?)>\\.(.*)/,\n /^Did not expect server HTML to contain the text node \"(.+?)\" in <(.+?)>\\.(.*)/,\n /^Text content did not match\\. Server: \"(.+?)\" Client: \"(.+?)\"(.*)/,\n]\n\nexport function testReactHydrationWarning(msg: string): boolean {\n if (typeof msg !== 'string' || !msg) return false\n // React 18 has the `Warning: ` prefix.\n // React 19 does not.\n if (msg.startsWith('Warning: ')) {\n msg = msg.slice('Warning: '.length)\n }\n return hydrationWarningRegexes.some((regex) => regex.test(msg))\n}\n\nexport function getHydrationErrorStackInfo(rawMessage: string): {\n message: string | null\n link?: string\n stack?: string\n diff?: string\n} {\n rawMessage = rawMessage.replace(/^Error: /, '')\n rawMessage = rawMessage.replace('Warning: ', '')\n const isReactHydrationWarning = testReactHydrationWarning(rawMessage)\n\n if (!isReactHydrationErrorMessage(rawMessage) && !isReactHydrationWarning) {\n return {\n message: null,\n link: '',\n stack: rawMessage,\n diff: '',\n }\n }\n\n if (isReactHydrationWarning) {\n const [message, diffLog] = rawMessage.split('\\n\\n')\n return {\n message: message.trim(),\n link: reactHydrationErrorDocLink,\n stack: '',\n diff: (diffLog || '').trim(),\n }\n }\n\n const firstLineBreak = rawMessage.indexOf('\\n')\n rawMessage = rawMessage.slice(firstLineBreak + 1).trim()\n\n const [message, trailing] = rawMessage.split(`${reactHydrationErrorDocLink}`)\n const trimmedMessage = message.trim()\n // React built-in hydration diff starts with a newline, checking if length is > 1\n if (trailing && trailing.length > 1) {\n const stacks: string[] = []\n const diffs: string[] = []\n trailing.split('\\n').forEach((line) => {\n if (line.trim() === '') return\n if (line.trim().startsWith('at ')) {\n stacks.push(line)\n } else {\n diffs.push(line)\n }\n })\n\n return {\n message: trimmedMessage,\n link: reactHydrationErrorDocLink,\n diff: diffs.join('\\n'),\n stack: stacks.join('\\n'),\n }\n } else {\n return {\n message: trimmedMessage,\n link: reactHydrationErrorDocLink,\n stack: trailing, // without hydration diff\n }\n }\n}\n"],"names":["getDefaultHydrationErrorMessage","getHydrationErrorStackInfo","isHydrationError","isReactHydrationErrorMessage","testReactHydrationWarning","hydrationErrorRegex","reactUnifiedMismatchWarning","reactHydrationStartMessages","reactHydrationErrorDocLink","error","isError","test","message","msg","some","prefix","startsWith","hydrationWarningRegexes","slice","length","regex","rawMessage","replace","isReactHydrationWarning","link","stack","diff","diffLog","split","trim","firstLineBreak","indexOf","trailing","trimmedMessage","stacks","diffs","forEach","line","push","join"],"mappings":";;;;;;;;;;;;;;;;;;IAcaA,+BAA+B;eAA/BA;;IAkCGC,0BAA0B;eAA1BA;;IA9BAC,gBAAgB;eAAhBA;;IAIAC,4BAA4B;eAA5BA;;IAgBAC,yBAAyB;eAAzBA;;;;kEAtCI;AAEpB,MAAMC,sBACJ;AAEF,MAAMC,8BAA+B;AAErC,MAAMC,8BAA8B;IAClCD;IACC;CACF;AAED,MAAME,6BAA6B;AAE5B,MAAMR,kCAAkC;IAC7C,OAAOM;AACT;AAEO,SAASJ,iBAAiBO,KAAc;IAC7C,OAAOC,IAAAA,gBAAO,EAACD,UAAUJ,oBAAoBM,IAAI,CAACF,MAAMG,OAAO;AACjE;AAEO,SAAST,6BAA6BU,GAAW;IACtD,OAAON,4BAA4BO,IAAI,CAAC,CAACC,SAAWF,IAAIG,UAAU,CAACD;AACrE;AAEA,MAAME,0BAA0B;IAC9B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAEM,SAASb,0BAA0BS,GAAW;IACnD,IAAI,OAAOA,QAAQ,YAAY,CAACA,KAAK,OAAO;IAC5C,uCAAuC;IACvC,qBAAqB;IACrB,IAAIA,IAAIG,UAAU,CAAC,cAAc;QAC/BH,MAAMA,IAAIK,KAAK,CAAC,YAAYC,MAAM;IACpC;IACA,OAAOF,wBAAwBH,IAAI,CAAC,CAACM,QAAUA,MAAMT,IAAI,CAACE;AAC5D;AAEO,SAASZ,2BAA2BoB,UAAkB;IAM3DA,aAAaA,WAAWC,OAAO,CAAC,YAAY;IAC5CD,aAAaA,WAAWC,OAAO,CAAC,aAAa;IAC7C,MAAMC,0BAA0BnB,0BAA0BiB;IAE1D,IAAI,CAAClB,6BAA6BkB,eAAe,CAACE,yBAAyB;QACzE,OAAO;YACLX,SAAS;YACTY,MAAM;YACNC,OAAOJ;YACPK,MAAM;QACR;IACF;IAEA,IAAIH,yBAAyB;QAC3B,MAAM,CAACX,SAASe,QAAQ,GAAGN,WAAWO,KAAK,CAAC;QAC5C,OAAO;YACLhB,SAASA,QAAQiB,IAAI;YACrBL,MAAMhB;YACNiB,OAAO;YACPC,MAAM,AAACC,CAAAA,WAAW,EAAC,EAAGE,IAAI;QAC5B;IACF;IAEA,MAAMC,iBAAiBT,WAAWU,OAAO,CAAC;IAC1CV,aAAaA,WAAWH,KAAK,CAACY,iBAAiB,GAAGD,IAAI;IAEtD,MAAM,CAACjB,SAASoB,SAAS,GAAGX,WAAWO,KAAK,CAAC,AAAC,KAAEpB;IAChD,MAAMyB,iBAAiBrB,QAAQiB,IAAI;IACnC,iFAAiF;IACjF,IAAIG,YAAYA,SAASb,MAAM,GAAG,GAAG;QACnC,MAAMe,SAAmB,EAAE;QAC3B,MAAMC,QAAkB,EAAE;QAC1BH,SAASJ,KAAK,CAAC,MAAMQ,OAAO,CAAC,CAACC;YAC5B,IAAIA,KAAKR,IAAI,OAAO,IAAI;YACxB,IAAIQ,KAAKR,IAAI,GAAGb,UAAU,CAAC,QAAQ;gBACjCkB,OAAOI,IAAI,CAACD;YACd,OAAO;gBACLF,MAAMG,IAAI,CAACD;YACb;QACF;QAEA,OAAO;YACLzB,SAASqB;YACTT,MAAMhB;YACNkB,MAAMS,MAAMI,IAAI,CAAC;YACjBd,OAAOS,OAAOK,IAAI,CAAC;QACrB;IACF,OAAO;QACL,OAAO;YACL3B,SAASqB;YACTT,MAAMhB;YACNiB,OAAOO;QACT;IACF;AACF"}
|
|
@@ -163,10 +163,9 @@ function Errors(param) {
|
|
|
163
163
|
hydrationWarning && (((_activeError_componentStackFrames = activeError.componentStackFrames) == null ? void 0 : _activeError_componentStackFrames.length) || !!errorDetails.reactOutputComponentDiff) ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_componentstackpseudohtml.PseudoHtmlDiff, {
|
|
164
164
|
className: "nextjs__container_errors__component-stack",
|
|
165
165
|
hydrationMismatchType: hydrationErrorType,
|
|
166
|
-
componentStackFrames: activeError.componentStackFrames || [],
|
|
167
166
|
firstContent: serverContent,
|
|
168
167
|
secondContent: clientContent,
|
|
169
|
-
reactOutputComponentDiff: errorDetails.reactOutputComponentDiff
|
|
168
|
+
reactOutputComponentDiff: errorDetails.reactOutputComponentDiff || ''
|
|
170
169
|
}) : null,
|
|
171
170
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_react.Suspense, {
|
|
172
171
|
fallback: /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
|
package/dist/client/components/react-dev-overlay/_experimental/internal/container/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/_experimental/internal/container/errors.tsx"],"sourcesContent":["import { useState, useMemo, useEffect, useRef, Suspense } from 'react'\nimport type { DebugInfo } from '../../../types'\nimport { Overlay } from '../components/overlay'\nimport { noop as css } from '../helpers/noop-template'\nimport { RuntimeError } from './runtime-error'\nimport { getErrorSource } from '../../../../../../shared/lib/error-source'\nimport { HotlinkedText } from '../components/hot-linked-text'\nimport { PseudoHtmlDiff } from './runtime-error/component-stack-pseudo-html'\nimport {\n type HydrationErrorState,\n getHydrationWarningType,\n} from '../../../../errors/hydration-error-info'\nimport {\n getUnhandledErrorType,\n isUnhandledConsoleOrRejection,\n} from '../../../../errors/console-error'\nimport { extractNextErrorCode } from '../../../../../../lib/error-telemetry-utils'\nimport { ErrorOverlayLayout } from '../components/errors/error-overlay-layout/error-overlay-layout'\nimport type { ReadyRuntimeError } from '../../../internal/helpers/get-error-by-type'\nimport type { ErrorBaseProps } from '../components/errors/error-overlay/error-overlay'\n\nexport interface ErrorsProps extends ErrorBaseProps {\n readyErrors: ReadyRuntimeError[]\n debugInfo: DebugInfo\n onClose: () => void\n}\n\ntype ReadyErrorEvent = ReadyRuntimeError\n\nfunction isNextjsLink(text: string): boolean {\n return text.startsWith('https://nextjs.org')\n}\n\nfunction ErrorDescription({\n error,\n hydrationWarning,\n}: {\n error: Error\n hydrationWarning: string | null\n}) {\n const isUnhandledOrReplayError = isUnhandledConsoleOrRejection(error)\n const unhandledErrorType = isUnhandledOrReplayError\n ? getUnhandledErrorType(error)\n : null\n const isConsoleErrorStringMessage = unhandledErrorType === 'string'\n // If the error is:\n // - hydration warning\n // - captured console error or unhandled rejection\n // skip displaying the error name\n const title =\n (isUnhandledOrReplayError && isConsoleErrorStringMessage) ||\n hydrationWarning\n ? ''\n : error.name + ': '\n\n // If it's replayed error, display the environment name\n const environmentName =\n 'environmentName' in error ? error['environmentName'] : ''\n const envPrefix = environmentName ? `[ ${environmentName} ] ` : ''\n return (\n <>\n {envPrefix}\n {title}\n <HotlinkedText\n text={hydrationWarning || error.message}\n matcher={isNextjsLink}\n />\n </>\n )\n}\n\nexport function Errors({\n readyErrors,\n debugInfo,\n onClose,\n ...props\n}: ErrorsProps) {\n const dialogResizerRef = useRef<HTMLDivElement | null>(null)\n\n useEffect(() => {\n // Close the error overlay when pressing escape\n function handleKeyDown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n onClose()\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [onClose])\n\n const isLoading = useMemo<boolean>(() => {\n return readyErrors.length < 1\n }, [readyErrors.length])\n\n const [activeIdx, setActiveIndex] = useState<number>(0)\n\n const activeError = useMemo<ReadyErrorEvent | null>(\n () => readyErrors[activeIdx] ?? null,\n [activeIdx, readyErrors]\n )\n\n if (isLoading) {\n // TODO: better loading state\n return <Overlay />\n }\n\n if (!activeError) {\n return null\n }\n\n const error = activeError.error\n const isServerError = ['server', 'edge-server'].includes(\n getErrorSource(error) || ''\n )\n const isUnhandledError = isUnhandledConsoleOrRejection(error)\n const errorDetails: HydrationErrorState = (error as any).details || {}\n const notes = errorDetails.notes || ''\n const [warningTemplate, serverContent, clientContent] =\n errorDetails.warning || [null, '', '']\n\n const hydrationErrorType = getHydrationWarningType(warningTemplate)\n const hydrationWarning = warningTemplate\n ? warningTemplate\n .replace('%s', serverContent)\n .replace('%s', clientContent)\n .replace('%s', '') // remove the %s for stack\n .replace(/%s$/, '') // If there's still a %s at the end, remove it\n .replace(/^Warning: /, '')\n .replace(/^Error: /, '')\n : null\n\n const errorCode = extractNextErrorCode(error)\n\n const footerMessage = isServerError\n ? 'This error happened while generating the page. Any console logs will be displayed in the terminal window.'\n : undefined\n\n return (\n <ErrorOverlayLayout\n errorCode={errorCode}\n errorType={\n isServerError\n ? 'Runtime Error'\n : isUnhandledError\n ? 'Console Error'\n : 'Unhandled Runtime Error'\n }\n errorMessage={\n <ErrorDescription error={error} hydrationWarning={hydrationWarning} />\n }\n onClose={isServerError ? undefined : onClose}\n debugInfo={debugInfo}\n error={error}\n readyErrors={readyErrors}\n activeIdx={activeIdx}\n setActiveIndex={setActiveIndex}\n footerMessage={footerMessage}\n dialogResizerRef={dialogResizerRef}\n {...props}\n >\n <div className=\"error-overlay-notes-container\">\n {notes ? (\n <>\n <p\n id=\"nextjs__container_errors__notes\"\n className=\"nextjs__container_errors__notes\"\n >\n {notes}\n </p>\n </>\n ) : null}\n {hydrationWarning ? (\n <p\n id=\"nextjs__container_errors__link\"\n className=\"nextjs__container_errors__link\"\n >\n <HotlinkedText text=\"See more info here: https://nextjs.org/docs/messages/react-hydration-error\" />\n </p>\n ) : null}\n </div>\n\n {hydrationWarning &&\n (activeError.componentStackFrames?.length ||\n !!errorDetails.reactOutputComponentDiff) ? (\n <PseudoHtmlDiff\n className=\"nextjs__container_errors__component-stack\"\n hydrationMismatchType={hydrationErrorType}\n componentStackFrames={activeError.componentStackFrames || []}\n firstContent={serverContent}\n secondContent={clientContent}\n reactOutputComponentDiff={errorDetails.reactOutputComponentDiff}\n />\n ) : null}\n <Suspense fallback={<div data-nextjs-error-suspended />}>\n <RuntimeError\n key={activeError.id.toString()}\n error={activeError}\n dialogResizerRef={dialogResizerRef}\n />\n </Suspense>\n </ErrorOverlayLayout>\n )\n}\n\nexport const styles = css`\n .nextjs-error-with-static {\n bottom: calc(var(--size-gap-double) * 4.5);\n }\n p.nextjs__container_errors__link {\n font-size: 14px;\n }\n p.nextjs__container_errors__notes {\n color: var(--color-stack-notes);\n font-size: 14px;\n line-height: 1.5;\n }\n .nextjs-container-errors-body > h2:not(:first-child) {\n margin-top: calc(var(--size-gap-double) + var(--size-gap));\n }\n .nextjs-container-errors-body > h2 {\n color: var(--color-title-color);\n margin-bottom: var(--size-gap);\n font-size: var(--size-font-big);\n }\n .nextjs-toast-errors-parent {\n cursor: pointer;\n transition: transform 0.2s ease;\n }\n .nextjs-toast-errors-parent:hover {\n transform: scale(1.1);\n }\n .nextjs-toast-errors {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n }\n .nextjs-toast-errors > svg {\n margin-right: var(--size-gap);\n }\n .nextjs-toast-hide-button {\n margin-left: var(--size-gap-triple);\n border: none;\n background: none;\n color: var(--color-ansi-bright-white);\n padding: 0;\n transition: opacity 0.25s ease;\n opacity: 0.7;\n }\n .nextjs-toast-hide-button:hover {\n opacity: 1;\n }\n .nextjs__container_errors_inspect_copy_button {\n cursor: pointer;\n background: none;\n border: none;\n color: var(--color-ansi-bright-white);\n font-size: 1.5rem;\n padding: 0;\n margin: 0;\n margin-left: var(--size-gap);\n transition: opacity 0.25s ease;\n }\n .nextjs__container_errors__error_title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--size-3);\n }\n .error-overlay-notes-container {\n padding: 0 var(--size-4);\n }\n .error-overlay-notes-container p {\n white-space: pre-wrap;\n }\n`\n"],"names":["Errors","styles","isNextjsLink","text","startsWith","ErrorDescription","error","hydrationWarning","isUnhandledOrReplayError","isUnhandledConsoleOrRejection","unhandledErrorType","getUnhandledErrorType","isConsoleErrorStringMessage","title","name","environmentName","envPrefix","HotlinkedText","message","matcher","readyErrors","debugInfo","onClose","props","activeError","dialogResizerRef","useRef","useEffect","handleKeyDown","event","key","document","addEventListener","removeEventListener","isLoading","useMemo","length","activeIdx","setActiveIndex","useState","Overlay","isServerError","includes","getErrorSource","isUnhandledError","errorDetails","details","notes","warningTemplate","serverContent","clientContent","warning","hydrationErrorType","getHydrationWarningType","replace","errorCode","extractNextErrorCode","footerMessage","undefined","ErrorOverlayLayout","errorType","errorMessage","div","className","p","id","componentStackFrames","reactOutputComponentDiff","PseudoHtmlDiff","hydrationMismatchType","firstContent","secondContent","Suspense","fallback","data-nextjs-error-suspended","RuntimeError","toString","css"],"mappings":";;;;;;;;;;;;;;;IAuEgBA,MAAM;eAANA;;IAsIHC,MAAM;eAANA;;;;;uBA7MkD;yBAEvC;8BACI;8BACC;6BACE;+BACD;0CACC;oCAIxB;8BAIA;qCAC8B;oCACF;;;;;;;;;;AAYnC,SAASC,aAAaC,IAAY;IAChC,OAAOA,KAAKC,UAAU,CAAC;AACzB;AAEA,SAASC,iBAAiB,KAMzB;IANyB,IAAA,EACxBC,KAAK,EACLC,gBAAgB,EAIjB,GANyB;IAOxB,MAAMC,2BAA2BC,IAAAA,2CAA6B,EAACH;IAC/D,MAAMI,qBAAqBF,2BACvBG,IAAAA,mCAAqB,EAACL,SACtB;IACJ,MAAMM,8BAA8BF,uBAAuB;IAC3D,mBAAmB;IACnB,sBAAsB;IACtB,kDAAkD;IAClD,iCAAiC;IACjC,MAAMG,QACJ,AAACL,4BAA4BI,+BAC7BL,mBACI,KACAD,MAAMQ,IAAI,GAAG;IAEnB,uDAAuD;IACvD,MAAMC,kBACJ,qBAAqBT,QAAQA,KAAK,CAAC,kBAAkB,GAAG;IAC1D,MAAMU,YAAYD,kBAAkB,AAAC,OAAIA,kBAAgB,QAAO;IAChE,qBACE;;YACGC;YACAH;0BACD,qBAACI,4BAAa;gBACZd,MAAMI,oBAAoBD,MAAMY,OAAO;gBACvCC,SAASjB;;;;AAIjB;AAEO,SAASF,OAAO,KAKT;IALS,IAAA,EACrBoB,WAAW,EACXC,SAAS,EACTC,OAAO,EACP,GAAGC,OACS,GALS;QAgHhBC;IA1GL,MAAMC,mBAAmBC,IAAAA,aAAM,EAAwB;IAEvDC,IAAAA,gBAAS,EAAC;QACR,+CAA+C;QAC/C,SAASC,cAAcC,KAAoB;YACzC,IAAIA,MAAMC,GAAG,KAAK,UAAU;gBAC1BR;YACF;QACF;QAEAS,SAASC,gBAAgB,CAAC,WAAWJ;QACrC,OAAO,IAAMG,SAASE,mBAAmB,CAAC,WAAWL;IACvD,GAAG;QAACN;KAAQ;IAEZ,MAAMY,YAAYC,IAAAA,cAAO,EAAU;QACjC,OAAOf,YAAYgB,MAAM,GAAG;IAC9B,GAAG;QAAChB,YAAYgB,MAAM;KAAC;IAEvB,MAAM,CAACC,WAAWC,eAAe,GAAGC,IAAAA,eAAQ,EAAS;IAErD,MAAMf,cAAcW,IAAAA,cAAO,EACzB;YAAMf;eAAAA,CAAAA,yBAAAA,WAAW,CAACiB,UAAU,YAAtBjB,yBAA0B;OAChC;QAACiB;QAAWjB;KAAY;IAG1B,IAAIc,WAAW;QACb,6BAA6B;QAC7B,qBAAO,qBAACM,gBAAO;IACjB;IAEA,IAAI,CAAChB,aAAa;QAChB,OAAO;IACT;IAEA,MAAMlB,QAAQkB,YAAYlB,KAAK;IAC/B,MAAMmC,gBAAgB;QAAC;QAAU;KAAc,CAACC,QAAQ,CACtDC,IAAAA,2BAAc,EAACrC,UAAU;IAE3B,MAAMsC,mBAAmBnC,IAAAA,2CAA6B,EAACH;IACvD,MAAMuC,eAAoC,AAACvC,MAAcwC,OAAO,IAAI,CAAC;IACrE,MAAMC,QAAQF,aAAaE,KAAK,IAAI;IACpC,MAAM,CAACC,iBAAiBC,eAAeC,cAAc,GACnDL,aAAaM,OAAO,IAAI;QAAC;QAAM;QAAI;KAAG;IAExC,MAAMC,qBAAqBC,IAAAA,2CAAuB,EAACL;IACnD,MAAMzC,mBAAmByC,kBACrBA,gBACGM,OAAO,CAAC,MAAML,eACdK,OAAO,CAAC,MAAMJ,eACdI,OAAO,CAAC,MAAM,IAAI,0BAA0B;KAC5CA,OAAO,CAAC,OAAO,IAAI,8CAA8C;KACjEA,OAAO,CAAC,cAAc,IACtBA,OAAO,CAAC,YAAY,MACvB;IAEJ,MAAMC,YAAYC,IAAAA,yCAAoB,EAAClD;IAEvC,MAAMmD,gBAAgBhB,gBAClB,8GACAiB;IAEJ,qBACE,sBAACC,sCAAkB;QACjBJ,WAAWA;QACXK,WACEnB,gBACI,kBACAG,mBACE,kBACA;QAERiB,4BACE,qBAACxD;YAAiBC,OAAOA;YAAOC,kBAAkBA;;QAEpDe,SAASmB,gBAAgBiB,YAAYpC;QACrCD,WAAWA;QACXf,OAAOA;QACPc,aAAaA;QACbiB,WAAWA;QACXC,gBAAgBA;QAChBmB,eAAeA;QACfhC,kBAAkBA;QACjB,GAAGF,KAAK;;0BAET,sBAACuC;gBAAIC,WAAU;;oBACZhB,sBACC;kCACE,cAAA,qBAACiB;4BACCC,IAAG;4BACHF,WAAU;sCAEThB;;yBAGH;oBACHxC,iCACC,qBAACyD;wBACCC,IAAG;wBACHF,WAAU;kCAEV,cAAA,qBAAC9C,4BAAa;4BAACd,MAAK;;yBAEpB;;;YAGLI,oBACAiB,CAAAA,EAAAA,oCAAAA,YAAY0C,oBAAoB,qBAAhC1C,kCAAkCY,MAAM,KACvC,CAAC,CAACS,aAAasB,wBAAwB,AAAD,kBACtC,qBAACC,wCAAc;gBACbL,WAAU;gBACVM,uBAAuBjB;gBACvBc,sBAAsB1C,YAAY0C,oBAAoB,IAAI,EAAE;gBAC5DI,cAAcrB;gBACdsB,eAAerB;gBACfiB,0BAA0BtB,aAAasB,wBAAwB;iBAE/D;0BACJ,qBAACK,eAAQ;gBAACC,wBAAU,qBAACX;oBAAIY,6BAA2B;;0BAClD,cAAA,qBAACC,0BAAY;oBAEXrE,OAAOkB;oBACPC,kBAAkBA;mBAFbD,YAAYyC,EAAE,CAACW,QAAQ;;;;AAOtC;AAEO,MAAM3E,aAAS4E,kBAAG"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/_experimental/internal/container/errors.tsx"],"sourcesContent":["import { useState, useMemo, useEffect, useRef, Suspense } from 'react'\nimport type { DebugInfo } from '../../../types'\nimport { Overlay } from '../components/overlay'\nimport { noop as css } from '../helpers/noop-template'\nimport { RuntimeError } from './runtime-error'\nimport { getErrorSource } from '../../../../../../shared/lib/error-source'\nimport { HotlinkedText } from '../components/hot-linked-text'\nimport { PseudoHtmlDiff } from './runtime-error/component-stack-pseudo-html'\nimport {\n type HydrationErrorState,\n getHydrationWarningType,\n} from '../../../../errors/hydration-error-info'\nimport {\n getUnhandledErrorType,\n isUnhandledConsoleOrRejection,\n} from '../../../../errors/console-error'\nimport { extractNextErrorCode } from '../../../../../../lib/error-telemetry-utils'\nimport { ErrorOverlayLayout } from '../components/errors/error-overlay-layout/error-overlay-layout'\nimport type { ReadyRuntimeError } from '../../../internal/helpers/get-error-by-type'\nimport type { ErrorBaseProps } from '../components/errors/error-overlay/error-overlay'\n\nexport interface ErrorsProps extends ErrorBaseProps {\n readyErrors: ReadyRuntimeError[]\n debugInfo: DebugInfo\n onClose: () => void\n}\n\ntype ReadyErrorEvent = ReadyRuntimeError\n\nfunction isNextjsLink(text: string): boolean {\n return text.startsWith('https://nextjs.org')\n}\n\nfunction ErrorDescription({\n error,\n hydrationWarning,\n}: {\n error: Error\n hydrationWarning: string | null\n}) {\n const isUnhandledOrReplayError = isUnhandledConsoleOrRejection(error)\n const unhandledErrorType = isUnhandledOrReplayError\n ? getUnhandledErrorType(error)\n : null\n const isConsoleErrorStringMessage = unhandledErrorType === 'string'\n // If the error is:\n // - hydration warning\n // - captured console error or unhandled rejection\n // skip displaying the error name\n const title =\n (isUnhandledOrReplayError && isConsoleErrorStringMessage) ||\n hydrationWarning\n ? ''\n : error.name + ': '\n\n // If it's replayed error, display the environment name\n const environmentName =\n 'environmentName' in error ? error['environmentName'] : ''\n const envPrefix = environmentName ? `[ ${environmentName} ] ` : ''\n return (\n <>\n {envPrefix}\n {title}\n <HotlinkedText\n text={hydrationWarning || error.message}\n matcher={isNextjsLink}\n />\n </>\n )\n}\n\nexport function Errors({\n readyErrors,\n debugInfo,\n onClose,\n ...props\n}: ErrorsProps) {\n const dialogResizerRef = useRef<HTMLDivElement | null>(null)\n\n useEffect(() => {\n // Close the error overlay when pressing escape\n function handleKeyDown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n onClose()\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [onClose])\n\n const isLoading = useMemo<boolean>(() => {\n return readyErrors.length < 1\n }, [readyErrors.length])\n\n const [activeIdx, setActiveIndex] = useState<number>(0)\n\n const activeError = useMemo<ReadyErrorEvent | null>(\n () => readyErrors[activeIdx] ?? null,\n [activeIdx, readyErrors]\n )\n\n if (isLoading) {\n // TODO: better loading state\n return <Overlay />\n }\n\n if (!activeError) {\n return null\n }\n\n const error = activeError.error\n const isServerError = ['server', 'edge-server'].includes(\n getErrorSource(error) || ''\n )\n const isUnhandledError = isUnhandledConsoleOrRejection(error)\n const errorDetails: HydrationErrorState = (error as any).details || {}\n const notes = errorDetails.notes || ''\n const [warningTemplate, serverContent, clientContent] =\n errorDetails.warning || [null, '', '']\n\n const hydrationErrorType = getHydrationWarningType(warningTemplate)\n const hydrationWarning = warningTemplate\n ? warningTemplate\n .replace('%s', serverContent)\n .replace('%s', clientContent)\n .replace('%s', '') // remove the %s for stack\n .replace(/%s$/, '') // If there's still a %s at the end, remove it\n .replace(/^Warning: /, '')\n .replace(/^Error: /, '')\n : null\n\n const errorCode = extractNextErrorCode(error)\n\n const footerMessage = isServerError\n ? 'This error happened while generating the page. Any console logs will be displayed in the terminal window.'\n : undefined\n\n return (\n <ErrorOverlayLayout\n errorCode={errorCode}\n errorType={\n isServerError\n ? 'Runtime Error'\n : isUnhandledError\n ? 'Console Error'\n : 'Unhandled Runtime Error'\n }\n errorMessage={\n <ErrorDescription error={error} hydrationWarning={hydrationWarning} />\n }\n onClose={isServerError ? undefined : onClose}\n debugInfo={debugInfo}\n error={error}\n readyErrors={readyErrors}\n activeIdx={activeIdx}\n setActiveIndex={setActiveIndex}\n footerMessage={footerMessage}\n dialogResizerRef={dialogResizerRef}\n {...props}\n >\n <div className=\"error-overlay-notes-container\">\n {notes ? (\n <>\n <p\n id=\"nextjs__container_errors__notes\"\n className=\"nextjs__container_errors__notes\"\n >\n {notes}\n </p>\n </>\n ) : null}\n {hydrationWarning ? (\n <p\n id=\"nextjs__container_errors__link\"\n className=\"nextjs__container_errors__link\"\n >\n <HotlinkedText text=\"See more info here: https://nextjs.org/docs/messages/react-hydration-error\" />\n </p>\n ) : null}\n </div>\n\n {hydrationWarning &&\n (activeError.componentStackFrames?.length ||\n !!errorDetails.reactOutputComponentDiff) ? (\n <PseudoHtmlDiff\n className=\"nextjs__container_errors__component-stack\"\n hydrationMismatchType={hydrationErrorType}\n firstContent={serverContent}\n secondContent={clientContent}\n reactOutputComponentDiff={errorDetails.reactOutputComponentDiff || ''}\n />\n ) : null}\n <Suspense fallback={<div data-nextjs-error-suspended />}>\n <RuntimeError\n key={activeError.id.toString()}\n error={activeError}\n dialogResizerRef={dialogResizerRef}\n />\n </Suspense>\n </ErrorOverlayLayout>\n )\n}\n\nexport const styles = css`\n .nextjs-error-with-static {\n bottom: calc(var(--size-gap-double) * 4.5);\n }\n p.nextjs__container_errors__link {\n font-size: 14px;\n }\n p.nextjs__container_errors__notes {\n color: var(--color-stack-notes);\n font-size: 14px;\n line-height: 1.5;\n }\n .nextjs-container-errors-body > h2:not(:first-child) {\n margin-top: calc(var(--size-gap-double) + var(--size-gap));\n }\n .nextjs-container-errors-body > h2 {\n color: var(--color-title-color);\n margin-bottom: var(--size-gap);\n font-size: var(--size-font-big);\n }\n .nextjs-toast-errors-parent {\n cursor: pointer;\n transition: transform 0.2s ease;\n }\n .nextjs-toast-errors-parent:hover {\n transform: scale(1.1);\n }\n .nextjs-toast-errors {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n }\n .nextjs-toast-errors > svg {\n margin-right: var(--size-gap);\n }\n .nextjs-toast-hide-button {\n margin-left: var(--size-gap-triple);\n border: none;\n background: none;\n color: var(--color-ansi-bright-white);\n padding: 0;\n transition: opacity 0.25s ease;\n opacity: 0.7;\n }\n .nextjs-toast-hide-button:hover {\n opacity: 1;\n }\n .nextjs__container_errors_inspect_copy_button {\n cursor: pointer;\n background: none;\n border: none;\n color: var(--color-ansi-bright-white);\n font-size: 1.5rem;\n padding: 0;\n margin: 0;\n margin-left: var(--size-gap);\n transition: opacity 0.25s ease;\n }\n .nextjs__container_errors__error_title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--size-3);\n }\n .error-overlay-notes-container {\n padding: 0 var(--size-4);\n }\n .error-overlay-notes-container p {\n white-space: pre-wrap;\n }\n`\n"],"names":["Errors","styles","isNextjsLink","text","startsWith","ErrorDescription","error","hydrationWarning","isUnhandledOrReplayError","isUnhandledConsoleOrRejection","unhandledErrorType","getUnhandledErrorType","isConsoleErrorStringMessage","title","name","environmentName","envPrefix","HotlinkedText","message","matcher","readyErrors","debugInfo","onClose","props","activeError","dialogResizerRef","useRef","useEffect","handleKeyDown","event","key","document","addEventListener","removeEventListener","isLoading","useMemo","length","activeIdx","setActiveIndex","useState","Overlay","isServerError","includes","getErrorSource","isUnhandledError","errorDetails","details","notes","warningTemplate","serverContent","clientContent","warning","hydrationErrorType","getHydrationWarningType","replace","errorCode","extractNextErrorCode","footerMessage","undefined","ErrorOverlayLayout","errorType","errorMessage","div","className","p","id","componentStackFrames","reactOutputComponentDiff","PseudoHtmlDiff","hydrationMismatchType","firstContent","secondContent","Suspense","fallback","data-nextjs-error-suspended","RuntimeError","toString","css"],"mappings":"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"}
|
|
@@ -1,57 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
* Format component stack into pseudo HTML
|
|
5
|
-
* component stack is an array of strings, e.g.: ['p', 'p', 'Page', ...]
|
|
6
|
-
*
|
|
7
|
-
* For html tags mismatch, it will render it for the code block
|
|
8
|
-
*
|
|
9
|
-
* ```
|
|
10
|
-
* <pre>
|
|
11
|
-
* <code>{`
|
|
12
|
-
* <Page>
|
|
13
|
-
* <p red>
|
|
14
|
-
* <p red>
|
|
15
|
-
* `}</code>
|
|
16
|
-
* </pre>
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* For text mismatch, it will render it for the code block
|
|
20
|
-
*
|
|
21
|
-
* ```
|
|
22
|
-
* <pre>
|
|
23
|
-
* <code>{`
|
|
24
|
-
* <Page>
|
|
25
|
-
* <p>
|
|
26
|
-
* "Server Text" (green)
|
|
27
|
-
* "Client Text" (red)
|
|
28
|
-
* </p>
|
|
29
|
-
* </Page>
|
|
30
|
-
* `}</code>
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* For bad text under a tag it will render it for the code block,
|
|
34
|
-
* e.g. "Mismatched Text" under <p>
|
|
35
|
-
*
|
|
36
|
-
* ```
|
|
37
|
-
* <pre>
|
|
38
|
-
* <code>{`
|
|
39
|
-
* <Page>
|
|
40
|
-
* <div>
|
|
41
|
-
* <p>
|
|
42
|
-
* "Mismatched Text" (red)
|
|
43
|
-
* </p>
|
|
44
|
-
* </div>
|
|
45
|
-
* </Page>
|
|
46
|
-
* `}</code>
|
|
47
|
-
* ```
|
|
48
|
-
*
|
|
49
|
-
*/
|
|
50
|
-
export declare function PseudoHtmlDiff({ componentStackFrames, firstContent, secondContent, hydrationMismatchType, reactOutputComponentDiff, ...props }: {
|
|
51
|
-
componentStackFrames: ComponentStackFrame[];
|
|
52
|
-
firstContent: string;
|
|
53
|
-
secondContent: string;
|
|
54
|
-
reactOutputComponentDiff: string | undefined;
|
|
55
|
-
hydrationMismatchType: 'tag' | 'text' | 'text-in-tag';
|
|
56
|
-
} & React.HTMLAttributes<HTMLPreElement>): import("react/jsx-runtime").JSX.Element;
|
|
1
|
+
export { PseudoHtmlDiff } from '../../../../hydration-diff/diff-view';
|
|
57
2
|
export declare const PSEUDO_HTML_DIFF_STYLES: string;
|