@lark-apaas/fullstack-vite-preset 1.0.32-alpha.4 → 1.0.32-alpha.6
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-overlay-plugin.d.ts","sourceRoot":"","sources":["../../src/vite-plugins/error-overlay-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAoC,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"error-overlay-plugin.d.ts","sourceRoot":"","sources":["../../src/vite-plugins/error-overlay-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAoC,MAAM,MAAM,CAAC;AAsErE,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiDD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,MAAM,CAmGR;AAED,eAAe,kBAAkB,CAAC"}
|
|
@@ -21,12 +21,6 @@ exports.errorOverlayPlugin = errorOverlayPlugin;
|
|
|
21
21
|
const fs_1 = __importDefault(require("fs"));
|
|
22
22
|
const path_1 = __importDefault(require("path"));
|
|
23
23
|
const OVERLAY_PATH = '/@error-overlay.js';
|
|
24
|
-
const VITE_ERROR_MARKER = 'new ErrorOverlay(error)';
|
|
25
|
-
// 贪婪捕获整个 payload object,避免 frame/message 里出现 `};\s*try` 时被非贪婪截断
|
|
26
|
-
const VITE_ERROR_PAYLOAD_RE = /const error = (\{[\s\S]+\});\s*try/;
|
|
27
|
-
const NODE_ENCODINGS = new Set([
|
|
28
|
-
'ascii', 'utf8', 'utf-8', 'utf16le', 'ucs2', 'ucs-2', 'base64', 'base64url', 'latin1', 'binary', 'hex',
|
|
29
|
-
]);
|
|
30
24
|
// 内联到 <script> 前必须转义 `<` `>` 和 line separator,避免 payload 里出现 `</script>` 破坏 script tag
|
|
31
25
|
function safeInlineJson(json) {
|
|
32
26
|
return json
|
|
@@ -35,6 +29,21 @@ function safeInlineJson(json) {
|
|
|
35
29
|
.replace(/\u2028/g, '\\u2028')
|
|
36
30
|
.replace(/\u2029/g, '\\u2029');
|
|
37
31
|
}
|
|
32
|
+
// 序列化 Vite 内部 err 对象为可 JSON 序列化的 payload,字段与 Vite prepareError 对齐
|
|
33
|
+
function serializeErrorPayload(err) {
|
|
34
|
+
const e = (err ?? {});
|
|
35
|
+
const stripAnsi = (s) => String(s ?? '').replace(/\x1b\[[0-9;]*m/g, '');
|
|
36
|
+
const payload = {
|
|
37
|
+
message: stripAnsi(e.message),
|
|
38
|
+
stack: stripAnsi(e.stack),
|
|
39
|
+
id: e.id ?? '',
|
|
40
|
+
frame: stripAnsi(e.frame ?? ''),
|
|
41
|
+
plugin: e.plugin ?? '',
|
|
42
|
+
pluginCode: e.pluginCode ? String(e.pluginCode) : '',
|
|
43
|
+
loc: e.loc ?? null,
|
|
44
|
+
};
|
|
45
|
+
return JSON.stringify(payload);
|
|
46
|
+
}
|
|
38
47
|
function buildCustomErrorHtml(errorPayloadJson, overlayPath) {
|
|
39
48
|
const escapedOverlayPath = JSON.stringify(overlayPath);
|
|
40
49
|
const safe = safeInlineJson(errorPayloadJson);
|
|
@@ -143,116 +152,7 @@ function errorOverlayPlugin(options = {}) {
|
|
|
143
152
|
configureServer(server) {
|
|
144
153
|
if (!enabled)
|
|
145
154
|
return;
|
|
146
|
-
//
|
|
147
|
-
// 改写内联 `new ErrorOverlay(error)`,让宿主 postMessage SELECTED_LOG + 加载自定义 overlay。
|
|
148
|
-
server.middlewares.use((req, res, next) => {
|
|
149
|
-
const origWriteHead = res.writeHead.bind(res);
|
|
150
|
-
const origWrite = res.write.bind(res);
|
|
151
|
-
const origEnd = res.end.bind(res);
|
|
152
|
-
const chunks = [];
|
|
153
|
-
let recordedStatus;
|
|
154
|
-
let recordedStatusMessage;
|
|
155
|
-
let recordedHeaders;
|
|
156
|
-
let headWasCalled = false;
|
|
157
|
-
let bypassed = false;
|
|
158
|
-
const bypass = () => {
|
|
159
|
-
if (bypassed)
|
|
160
|
-
return;
|
|
161
|
-
bypassed = true;
|
|
162
|
-
res.writeHead = origWriteHead;
|
|
163
|
-
res.write = origWrite;
|
|
164
|
-
res.end = origEnd;
|
|
165
|
-
if (headWasCalled && recordedStatus != null) {
|
|
166
|
-
origWriteHead(recordedStatus, recordedStatusMessage, recordedHeaders);
|
|
167
|
-
}
|
|
168
|
-
for (const c of chunks)
|
|
169
|
-
origWrite(c);
|
|
170
|
-
};
|
|
171
|
-
res.writeHead = (status, statusMessage, headers) => {
|
|
172
|
-
if (bypassed)
|
|
173
|
-
return origWriteHead(status, statusMessage, headers);
|
|
174
|
-
if (status !== 500) {
|
|
175
|
-
recordedStatus = status;
|
|
176
|
-
recordedStatusMessage = statusMessage;
|
|
177
|
-
recordedHeaders = headers;
|
|
178
|
-
headWasCalled = true;
|
|
179
|
-
bypass();
|
|
180
|
-
return res;
|
|
181
|
-
}
|
|
182
|
-
recordedStatus = status;
|
|
183
|
-
recordedStatusMessage = statusMessage;
|
|
184
|
-
recordedHeaders = headers;
|
|
185
|
-
headWasCalled = true;
|
|
186
|
-
return res;
|
|
187
|
-
};
|
|
188
|
-
// Node signature: res.write(chunk[, encoding][, cb]). encoding 是 chunk 的字符编码,不是数据本身
|
|
189
|
-
const collectChunk = (chunk, encoding) => {
|
|
190
|
-
if (chunk == null)
|
|
191
|
-
return;
|
|
192
|
-
if (typeof chunk === 'function')
|
|
193
|
-
return;
|
|
194
|
-
if (Buffer.isBuffer(chunk)) {
|
|
195
|
-
chunks.push(chunk);
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
const enc = typeof encoding === 'string' && NODE_ENCODINGS.has(encoding.toLowerCase())
|
|
199
|
-
? encoding
|
|
200
|
-
: 'utf-8';
|
|
201
|
-
chunks.push(Buffer.from(String(chunk), enc));
|
|
202
|
-
};
|
|
203
|
-
res.write = (chunk, encoding, ..._rest) => {
|
|
204
|
-
if (bypassed)
|
|
205
|
-
return origWrite(chunk, encoding, ..._rest);
|
|
206
|
-
collectChunk(chunk, encoding);
|
|
207
|
-
return true;
|
|
208
|
-
};
|
|
209
|
-
res.end = (chunk, encoding, ..._rest) => {
|
|
210
|
-
if (bypassed)
|
|
211
|
-
return origEnd(chunk, encoding, ..._rest);
|
|
212
|
-
collectChunk(chunk, encoding);
|
|
213
|
-
const status = headWasCalled && recordedStatus != null ? recordedStatus : res.statusCode;
|
|
214
|
-
const body = Buffer.concat(chunks).toString('utf-8');
|
|
215
|
-
if (status !== 500 || !body.includes(VITE_ERROR_MARKER)) {
|
|
216
|
-
bypass();
|
|
217
|
-
return origEnd();
|
|
218
|
-
}
|
|
219
|
-
const m = body.match(VITE_ERROR_PAYLOAD_RE);
|
|
220
|
-
if (!m) {
|
|
221
|
-
bypass();
|
|
222
|
-
return origEnd();
|
|
223
|
-
}
|
|
224
|
-
try {
|
|
225
|
-
// 校验捕获的 payload 是合法 JSON,防御性拒绝异常输入
|
|
226
|
-
JSON.parse(m[1]);
|
|
227
|
-
const newHtml = buildCustomErrorHtml(m[1], overlayPath);
|
|
228
|
-
const buf = Buffer.from(newHtml, 'utf-8');
|
|
229
|
-
bypassed = true;
|
|
230
|
-
res.writeHead = origWriteHead;
|
|
231
|
-
res.write = origWrite;
|
|
232
|
-
res.end = origEnd;
|
|
233
|
-
// 保留 Vite 或下游 middleware 通过 writeHead(status, headers) 传入的原始 headers
|
|
234
|
-
// (CORS / Cache-Control / cookies 等),Content-Type/Content-Length 由下面覆盖
|
|
235
|
-
if (recordedHeaders && typeof recordedHeaders === 'object' && !Array.isArray(recordedHeaders)) {
|
|
236
|
-
for (const [k, v] of Object.entries(recordedHeaders)) {
|
|
237
|
-
try {
|
|
238
|
-
res.setHeader(k, v);
|
|
239
|
-
}
|
|
240
|
-
catch { /* skip invalid header */ }
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
244
|
-
res.setHeader('Content-Length', String(buf.length));
|
|
245
|
-
res.statusCode = 500;
|
|
246
|
-
return origEnd(buf);
|
|
247
|
-
}
|
|
248
|
-
catch (err) {
|
|
249
|
-
console.error('[error-overlay] rewrite failed:', err);
|
|
250
|
-
bypass();
|
|
251
|
-
return origEnd();
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
next();
|
|
255
|
-
});
|
|
155
|
+
// Serve /@error-overlay.js (URL-matched; safe to register early).
|
|
256
156
|
server.middlewares.use((req, res, next) => {
|
|
257
157
|
if (req.url !== overlayPath)
|
|
258
158
|
return next();
|
|
@@ -268,6 +168,33 @@ function errorOverlayPlugin(options = {}) {
|
|
|
268
168
|
res.end(`// Error: ${e}`);
|
|
269
169
|
}
|
|
270
170
|
});
|
|
171
|
+
// 拦截 Vite compile / transform 抛出的 err,替代 Vite 内置的 500 error HTML (`new ErrorOverlay(error)`)
|
|
172
|
+
// 为我们的 postMessage SELECTED_LOG + 加载自定义 overlay 响应。
|
|
173
|
+
// 关键:必须走 configureServer 返回的 post-hook,让本 middleware 位于 stack 中
|
|
174
|
+
// transformMiddleware/htmlFallbackMiddleware 之后、Vite 自身 errorMiddleware 之前;
|
|
175
|
+
// 这样 next(err) 才会先命中我们。
|
|
176
|
+
return () => {
|
|
177
|
+
// 4-arg error middleware (connect 的错误路径要求 4 参数签名)。
|
|
178
|
+
const compileErrorHandler = (err, _req, res, next) => {
|
|
179
|
+
try {
|
|
180
|
+
if (res.writableEnded || res.headersSent) {
|
|
181
|
+
return next(err);
|
|
182
|
+
}
|
|
183
|
+
const payloadJson = serializeErrorPayload(err);
|
|
184
|
+
const html = buildCustomErrorHtml(payloadJson, overlayPath);
|
|
185
|
+
const buf = Buffer.from(html, 'utf-8');
|
|
186
|
+
res.statusCode = 500;
|
|
187
|
+
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
188
|
+
res.setHeader('Content-Length', String(buf.length));
|
|
189
|
+
res.end(buf);
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
console.error('[error-overlay] error middleware failed:', e);
|
|
193
|
+
return next(err);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
server.middlewares.use(compileErrorHandler);
|
|
197
|
+
};
|
|
271
198
|
},
|
|
272
199
|
// HTML 注入 script
|
|
273
200
|
transformIndexHtml(html) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-overlay-plugin.js","sourceRoot":"","sources":["../../src/vite-plugins/error-overlay-plugin.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;;;
|
|
1
|
+
{"version":3,"file":"error-overlay-plugin.js","sourceRoot":"","sources":["../../src/vite-plugins/error-overlay-plugin.ts"],"names":[],"mappings":"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"}
|