@pubinfo/vite 2.0.0-rc.2 → 2.0.0-rc.4
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/dist/index.d.ts +0 -4
- package/dist/index.js +155 -98
- package/dist/load.js +267 -0
- package/package.json +7 -6
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { defineConfig, loadEnv, mergeConfig } from "rolldown-vite";
|
|
2
|
+
import { defineConfig, loadEnv, mergeConfig, normalizePath } from "rolldown-vite";
|
|
3
3
|
import { cwd } from "node:process";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import consola from "consola";
|
|
6
|
-
import { join, posix, relative, resolve } from "node:path";
|
|
6
|
+
import { dirname, join, posix, relative, resolve } from "node:path";
|
|
7
7
|
import vue from "@vitejs/plugin-vue";
|
|
8
8
|
import vueJsx from "@vitejs/plugin-vue-jsx";
|
|
9
9
|
import autoImport from "unplugin-auto-import/vite";
|
|
@@ -17,13 +17,15 @@ import boxen from "boxen";
|
|
|
17
17
|
import { libInjectCss } from "vite-plugin-lib-inject-css";
|
|
18
18
|
import VueDevTools from "vite-plugin-vue-devtools";
|
|
19
19
|
import vueLegacy from "@vitejs/plugin-legacy";
|
|
20
|
-
import { createHash } from "node:crypto";
|
|
21
|
-
import { existsSync, statSync } from "node:fs";
|
|
22
20
|
import fg from "fast-glob";
|
|
23
21
|
import { merge } from "lodash-es";
|
|
22
|
+
import picomatch from "picomatch";
|
|
23
|
+
import { existsSync } from "node:fs";
|
|
24
24
|
import { vitePluginFakeServer } from "vite-plugin-fake-server";
|
|
25
25
|
import OpenAPI from "@pubinfo/unplugin-openapi/vite";
|
|
26
26
|
import Unocss from "unocss/vite";
|
|
27
|
+
import { readFile } from "node:fs/promises";
|
|
28
|
+
import { fileURLToPath } from "node:url";
|
|
27
29
|
|
|
28
30
|
export * from "rolldown-vite"
|
|
29
31
|
|
|
@@ -68,17 +70,20 @@ function getServerProxy(env, isProxy) {
|
|
|
68
70
|
//#endregion
|
|
69
71
|
//#region src/plugins/auto-import.ts
|
|
70
72
|
function createAutoImport() {
|
|
71
|
-
return
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
return {
|
|
74
|
+
...autoImport({
|
|
75
|
+
imports: [
|
|
76
|
+
"vue",
|
|
77
|
+
"vue-router",
|
|
78
|
+
"pinia",
|
|
79
|
+
{ pubinfo: ["useAuth"] }
|
|
80
|
+
],
|
|
81
|
+
ignore: ["h"],
|
|
82
|
+
dts: "./.pubinfo/auto-imports.d.ts",
|
|
83
|
+
resolvers: [AntDesignVueResolver(), IconsResolver({ prefix: "i" })]
|
|
84
|
+
}),
|
|
85
|
+
enforce: "pre"
|
|
86
|
+
};
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
//#endregion
|
|
@@ -101,12 +106,11 @@ function createComponents() {
|
|
|
101
106
|
{
|
|
102
107
|
type: "component",
|
|
103
108
|
resolve(name) {
|
|
104
|
-
|
|
109
|
+
if ([
|
|
105
110
|
"PubinfoApp",
|
|
106
111
|
"PubinfoProvider",
|
|
107
112
|
"PubinfoIcon"
|
|
108
|
-
]
|
|
109
|
-
if (components$1.includes(name)) return {
|
|
113
|
+
].includes(name)) return {
|
|
110
114
|
name,
|
|
111
115
|
from: "pubinfo"
|
|
112
116
|
};
|
|
@@ -138,10 +142,13 @@ function createCompression(env) {
|
|
|
138
142
|
//#endregion
|
|
139
143
|
//#region src/plugins/dts.ts
|
|
140
144
|
function createDTS() {
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
+
return {
|
|
146
|
+
...dts({
|
|
147
|
+
clearPureImport: false,
|
|
148
|
+
exclude: ["tests/**/*"]
|
|
149
|
+
}),
|
|
150
|
+
enforce: "post"
|
|
151
|
+
};
|
|
145
152
|
}
|
|
146
153
|
|
|
147
154
|
//#endregion
|
|
@@ -227,33 +234,66 @@ function getPatternBase(pattern) {
|
|
|
227
234
|
}
|
|
228
235
|
return baseParts.join("/");
|
|
229
236
|
}
|
|
230
|
-
function normalizePath(path) {
|
|
237
|
+
function normalizePath$1(path) {
|
|
231
238
|
return posix.normalize(path.replace(/\\/g, "/"));
|
|
232
239
|
}
|
|
233
240
|
function libResolverPlugin(options) {
|
|
234
241
|
const virtualModuleId = "virtual:pubinfo-resolver";
|
|
235
242
|
const resolvedId = `\0${virtualModuleId}`;
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
243
|
+
let serverRoot = "";
|
|
244
|
+
function sendUpdate(server, action, file) {
|
|
245
|
+
const payload = {
|
|
246
|
+
action,
|
|
247
|
+
file,
|
|
248
|
+
timestamp: Date.now()
|
|
249
|
+
};
|
|
250
|
+
server.ws.send({
|
|
251
|
+
type: "custom",
|
|
252
|
+
event: "pubinfo-resolver:update",
|
|
253
|
+
data: payload
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
function isMatchingFile(file) {
|
|
257
|
+
const normalizedFile = normalizePath$1(file);
|
|
258
|
+
const isVueOrTsFile = /\.(vue|tsx?|jsx?)$/.test(normalizedFile);
|
|
259
|
+
const relativePath = serverRoot ? normalizePath$1(relative(serverRoot, normalizedFile)) : normalizedFile;
|
|
260
|
+
return Object.values(options.entries).some((pattern, index) => {
|
|
261
|
+
return picomatch(pattern)(relativePath);
|
|
262
|
+
}) && isVueOrTsFile;
|
|
263
|
+
}
|
|
239
264
|
return {
|
|
240
265
|
name: "vite-plugin-lib-resolver",
|
|
241
266
|
enforce: "pre",
|
|
242
|
-
buildStart() {
|
|
243
|
-
|
|
267
|
+
buildStart() {},
|
|
268
|
+
configureServer(server) {
|
|
269
|
+
serverRoot = server.config.root;
|
|
270
|
+
const encodedPath = "/@id/__x00__virtual:pubinfo-resolver";
|
|
271
|
+
server.middlewares.use((req, _res, next) => {
|
|
272
|
+
if (req.url && req.url.startsWith(encodedPath)) {
|
|
273
|
+
const mod = server.moduleGraph.getModuleById(resolvedId);
|
|
274
|
+
if (mod) server.moduleGraph.invalidateModule(mod);
|
|
275
|
+
}
|
|
276
|
+
next();
|
|
277
|
+
});
|
|
278
|
+
server.watcher.on("add", (file) => {
|
|
279
|
+
if (isMatchingFile(file)) sendUpdate(server, "add", file);
|
|
280
|
+
});
|
|
281
|
+
server.watcher.on("unlink", (file) => {
|
|
282
|
+
if (isMatchingFile(file)) sendUpdate(server, "unlink", file);
|
|
283
|
+
});
|
|
284
|
+
const patterns = Object.values(options.entries);
|
|
285
|
+
const bases = patterns.map((pattern) => {
|
|
286
|
+
const base = getPatternBase(pattern);
|
|
287
|
+
return resolve(server.config.root, base);
|
|
288
|
+
});
|
|
289
|
+
server.watcher.add([...patterns.map((p) => resolve(server.config.root, p)), ...bases]);
|
|
244
290
|
},
|
|
245
291
|
async resolveId(id) {
|
|
246
292
|
return id === virtualModuleId ? resolvedId : null;
|
|
247
293
|
},
|
|
248
294
|
async load(id) {
|
|
249
295
|
if (id !== resolvedId) return null;
|
|
250
|
-
|
|
251
|
-
if (enableCache && cache.has(configHash)) {
|
|
252
|
-
const cached = cache.get(configHash);
|
|
253
|
-
const hasChanges = await checkForFileChanges(options.entries, cached.fileHashes);
|
|
254
|
-
if (!hasChanges) return cached.content;
|
|
255
|
-
}
|
|
256
|
-
const moduleResults = await Promise.all(Object.entries(options.entries).map(async ([key, pattern]) => {
|
|
296
|
+
return `export default {\n ${(await Promise.all(Object.entries(options.entries).map(async ([key, pattern]) => {
|
|
257
297
|
try {
|
|
258
298
|
const files = await fg(pattern, { absolute: true });
|
|
259
299
|
if (files.length === 0) return {
|
|
@@ -263,10 +303,9 @@ function libResolverPlugin(options) {
|
|
|
263
303
|
};
|
|
264
304
|
const base = getPatternBase(pattern);
|
|
265
305
|
const imports = files.map((file) => {
|
|
266
|
-
const absPath = normalizePath(file);
|
|
267
|
-
const relToBase = normalizePath(relative(resolve(base), file));
|
|
268
|
-
|
|
269
|
-
return `"${relPath}": () => import("${absPath}")`;
|
|
306
|
+
const absPath = normalizePath$1(file);
|
|
307
|
+
const relToBase = normalizePath$1(relative(resolve(base), file));
|
|
308
|
+
return `"${posix.join(base, relToBase)}": () => import("${absPath}")`;
|
|
270
309
|
}).join(",\n");
|
|
271
310
|
return {
|
|
272
311
|
key,
|
|
@@ -281,60 +320,16 @@ function libResolverPlugin(options) {
|
|
|
281
320
|
files: []
|
|
282
321
|
};
|
|
283
322
|
}
|
|
284
|
-
}))
|
|
285
|
-
const moduleDefs = moduleResults.map((result) => result.content);
|
|
286
|
-
const content = `export default {\n ${moduleDefs.join(",\n ")}\n}`;
|
|
287
|
-
const fileHashes = /* @__PURE__ */ new Map();
|
|
288
|
-
const allFiles = moduleResults.flatMap((result) => result.files);
|
|
289
|
-
for (const file of allFiles) if (existsSync(file)) {
|
|
290
|
-
const stats = statSync(file);
|
|
291
|
-
const fileHash = createHash("md5").update(`${file}-${stats.mtimeMs}-${stats.size}`).digest("hex");
|
|
292
|
-
fileHashes.set(file, fileHash);
|
|
293
|
-
}
|
|
294
|
-
if (enableCache) {
|
|
295
|
-
if (cache.size >= maxCacheSize) {
|
|
296
|
-
const oldestKey = cache.keys().next().value;
|
|
297
|
-
if (oldestKey) cache.delete(oldestKey);
|
|
298
|
-
}
|
|
299
|
-
cache.set(configHash, {
|
|
300
|
-
content,
|
|
301
|
-
fileHashes,
|
|
302
|
-
timestamp: Date.now()
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
return content;
|
|
323
|
+
}))).map((result) => result.content).join(",\n ")}\n}`;
|
|
306
324
|
}
|
|
307
325
|
};
|
|
308
|
-
async function checkForFileChanges(entries, cachedFileHashes) {
|
|
309
|
-
try {
|
|
310
|
-
for (const pattern of Object.values(entries)) {
|
|
311
|
-
const files = await fg(pattern, { absolute: true });
|
|
312
|
-
for (const file of files) {
|
|
313
|
-
if (!existsSync(file)) return true;
|
|
314
|
-
const stats = statSync(file);
|
|
315
|
-
const currentFileHash = createHash("md5").update(`${file}-${stats.mtimeMs}-${stats.size}`).digest("hex");
|
|
316
|
-
const cachedHash = cachedFileHashes.get(file);
|
|
317
|
-
if (!cachedHash || cachedHash !== currentFileHash) return true;
|
|
318
|
-
}
|
|
319
|
-
for (const cachedFile of cachedFileHashes.keys()) if (!files.includes(cachedFile) && existsSync(cachedFile)) return true;
|
|
320
|
-
}
|
|
321
|
-
return false;
|
|
322
|
-
} catch (error) {
|
|
323
|
-
console.warn("[lib-resolver] Error checking file changes:", error);
|
|
324
|
-
return true;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
326
|
}
|
|
328
327
|
function createLibResolver(options) {
|
|
329
|
-
return libResolverPlugin(merge({
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
},
|
|
335
|
-
cache: true,
|
|
336
|
-
maxCacheSize: 50
|
|
337
|
-
}, options));
|
|
328
|
+
return libResolverPlugin(merge({ entries: {
|
|
329
|
+
icons: "src/assets/icons/**/*",
|
|
330
|
+
layouts: "src/layouts/*.vue",
|
|
331
|
+
pages: "src/views/**/*.vue"
|
|
332
|
+
} }, options));
|
|
338
333
|
}
|
|
339
334
|
|
|
340
335
|
//#endregion
|
|
@@ -362,10 +357,75 @@ function createUnocss() {
|
|
|
362
357
|
return Unocss();
|
|
363
358
|
}
|
|
364
359
|
|
|
360
|
+
//#endregion
|
|
361
|
+
//#region src/plugins/virtual-inspector.ts
|
|
362
|
+
function getInspectorPath() {
|
|
363
|
+
return normalizePath(dirname(fileURLToPath(import.meta.url)));
|
|
364
|
+
}
|
|
365
|
+
function createVirtualInspectorPlugin(options = {}) {
|
|
366
|
+
const { enabled = true } = options;
|
|
367
|
+
const inspectorPath = getInspectorPath();
|
|
368
|
+
const virtualModuleId = "virtual:vite-pubinfo-inspector:load.js";
|
|
369
|
+
let config;
|
|
370
|
+
return {
|
|
371
|
+
name: "vite-plugin-virtual-inspector",
|
|
372
|
+
enforce: "pre",
|
|
373
|
+
configureServer(server) {
|
|
374
|
+
if (!enabled) return;
|
|
375
|
+
server.middlewares.use("/__pubinfo_inspector__", (req, res, next) => {
|
|
376
|
+
if (req.url === "/info") {
|
|
377
|
+
res.setHeader("Content-Type", "application/json");
|
|
378
|
+
res.end(JSON.stringify({
|
|
379
|
+
virtualModule: virtualModuleId,
|
|
380
|
+
enabled: true,
|
|
381
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
382
|
+
}));
|
|
383
|
+
} else next();
|
|
384
|
+
});
|
|
385
|
+
},
|
|
386
|
+
async resolveId(importee) {
|
|
387
|
+
if (importee === virtualModuleId) return resolve(inspectorPath, "load.js");
|
|
388
|
+
return null;
|
|
389
|
+
},
|
|
390
|
+
async load(id) {
|
|
391
|
+
if (id.includes("load.js") && id.includes(inspectorPath)) {
|
|
392
|
+
if (!enabled) return "export default {};";
|
|
393
|
+
const filePath = resolve(inspectorPath, "load.js");
|
|
394
|
+
if (existsSync(filePath)) return await readFile(filePath, "utf-8");
|
|
395
|
+
else {
|
|
396
|
+
console.error(`Failed to find file for pubinfo-inspector: ${filePath}`);
|
|
397
|
+
return "export default { error: \"Failed to load inspector content\" };";
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return null;
|
|
401
|
+
},
|
|
402
|
+
transformIndexHtml(html) {
|
|
403
|
+
if (!enabled) return;
|
|
404
|
+
return {
|
|
405
|
+
html,
|
|
406
|
+
tags: [{
|
|
407
|
+
tag: "script",
|
|
408
|
+
injectTo: "head",
|
|
409
|
+
attrs: {
|
|
410
|
+
type: "module",
|
|
411
|
+
src: `${config?.base || "/"}@id/${virtualModuleId}`
|
|
412
|
+
}
|
|
413
|
+
}]
|
|
414
|
+
};
|
|
415
|
+
},
|
|
416
|
+
configResolved(resolvedConfig) {
|
|
417
|
+
config = resolvedConfig;
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function createVirtualInspector(options) {
|
|
422
|
+
return createVirtualInspectorPlugin(options);
|
|
423
|
+
}
|
|
424
|
+
|
|
365
425
|
//#endregion
|
|
366
426
|
//#region src/plugins/index.ts
|
|
367
427
|
function createVitePlugins(viteEnv, isBuild = false, config, type) {
|
|
368
|
-
|
|
428
|
+
return [
|
|
369
429
|
vue(),
|
|
370
430
|
vueJsx(),
|
|
371
431
|
createLegacy(viteEnv),
|
|
@@ -378,10 +438,10 @@ function createVitePlugins(viteEnv, isBuild = false, config, type) {
|
|
|
378
438
|
createOpenAPI(config.openapi),
|
|
379
439
|
createLibResolver(config.resolver),
|
|
380
440
|
appInfo(),
|
|
441
|
+
createVirtualInspector({ enabled: true }),
|
|
381
442
|
type === "module" ? [createDTS(), createInjectCSS()] : null,
|
|
382
443
|
isBuild ? createCompression(viteEnv) : null
|
|
383
|
-
];
|
|
384
|
-
return vitePlugins.filter(Boolean);
|
|
444
|
+
].filter(Boolean);
|
|
385
445
|
}
|
|
386
446
|
|
|
387
447
|
//#endregion
|
|
@@ -393,13 +453,12 @@ function createDefaultAppConfig(config) {
|
|
|
393
453
|
const timestamp = (/* @__PURE__ */ new Date()).getTime();
|
|
394
454
|
const env = loadEnv(mode, root);
|
|
395
455
|
const { VITE_OPEN_PROXY, VITE_BUILD_SOURCEMAP } = env;
|
|
396
|
-
|
|
397
|
-
const applicationConfig = {
|
|
456
|
+
return {
|
|
398
457
|
base: "./",
|
|
399
458
|
server: {
|
|
400
459
|
open: true,
|
|
401
460
|
host: true,
|
|
402
|
-
proxy:
|
|
461
|
+
proxy: getServerProxy(env, !isBuild && VITE_OPEN_PROXY === "true"),
|
|
403
462
|
warmup: { clientFiles: ["./index.html"] }
|
|
404
463
|
},
|
|
405
464
|
optimizeDeps: { exclude: [
|
|
@@ -423,7 +482,6 @@ function createDefaultAppConfig(config) {
|
|
|
423
482
|
},
|
|
424
483
|
plugins: createVitePlugins(env, isBuild, config, "app")
|
|
425
484
|
};
|
|
426
|
-
return applicationConfig;
|
|
427
485
|
};
|
|
428
486
|
}
|
|
429
487
|
|
|
@@ -434,7 +492,7 @@ function createDefaultModuleConfig(config) {
|
|
|
434
492
|
const root = cwd();
|
|
435
493
|
const isBuild = command === "build";
|
|
436
494
|
const env = loadEnv(mode, root);
|
|
437
|
-
|
|
495
|
+
return {
|
|
438
496
|
optimizeDeps: { exclude: [
|
|
439
497
|
"pubinfo",
|
|
440
498
|
"@pubinfo/core",
|
|
@@ -452,7 +510,6 @@ function createDefaultModuleConfig(config) {
|
|
|
452
510
|
} },
|
|
453
511
|
plugins: createVitePlugins(env, isBuild, config, "module")
|
|
454
512
|
};
|
|
455
|
-
return applicationConfig;
|
|
456
513
|
};
|
|
457
514
|
}
|
|
458
515
|
|
package/dist/load.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// Vite Pubinfo Inspector Virtual Module
|
|
2
|
+
|
|
3
|
+
// 检查器工具函数
|
|
4
|
+
export const inspectorUtils = {
|
|
5
|
+
// 获取当前环境信息
|
|
6
|
+
getEnvInfo() {
|
|
7
|
+
return {
|
|
8
|
+
nodeEnv: 'development', // 简化处理,直接设置为开发模式
|
|
9
|
+
mode: import.meta.env.MODE,
|
|
10
|
+
dev: import.meta.env.DEV,
|
|
11
|
+
prod: import.meta.env.PROD,
|
|
12
|
+
ssr: import.meta.env.SSR,
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
// 获取Vite信息
|
|
17
|
+
getViteInfo() {
|
|
18
|
+
return {
|
|
19
|
+
hmr: import.meta.hot ? 'enabled' : 'disabled',
|
|
20
|
+
base: import.meta.env.BASE_URL,
|
|
21
|
+
url: import.meta.url,
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// WebSocket 连接工具
|
|
26
|
+
websocket: {
|
|
27
|
+
// 获取 HMR WebSocket 连接信息
|
|
28
|
+
getHMRConnection() {
|
|
29
|
+
if (!import.meta.hot) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 通过 import.meta.hot 获取内部的 transport 和连接信息
|
|
34
|
+
// 注意:这些是内部 API,可能会在 Vite 版本更新时发生变化
|
|
35
|
+
const hotContext = import.meta.hot;
|
|
36
|
+
|
|
37
|
+
// 尝试访问内部的 HMR 客户端
|
|
38
|
+
const hmrClient = hotContext?.__viteHmrClient || hotContext?._hmrClient;
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
isAvailable: !!hotContext,
|
|
42
|
+
client: hmrClient,
|
|
43
|
+
// 提供一些基本的连接信息
|
|
44
|
+
connectionState: hmrClient?.transport ? 'connected' : 'disconnected',
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
// 发送自定义 WebSocket 消息
|
|
49
|
+
send(event, data) {
|
|
50
|
+
if (!import.meta.hot) {
|
|
51
|
+
console.warn('[Pubinfo Inspector] HMR not available');
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
import.meta.hot.send(event, data);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('[Pubinfo Inspector] Failed to send WebSocket message:', error);
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// 监听自定义 WebSocket 事件
|
|
66
|
+
on(event, callback) {
|
|
67
|
+
if (!import.meta.hot) {
|
|
68
|
+
console.warn('[Pubinfo Inspector] HMR not available');
|
|
69
|
+
return () => {};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
import.meta.hot.on(event, callback);
|
|
74
|
+
|
|
75
|
+
// 返回取消监听的函数
|
|
76
|
+
return () => {
|
|
77
|
+
try {
|
|
78
|
+
import.meta.hot.off(event, callback);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
console.error('[Pubinfo Inspector] Failed to remove WebSocket listener:', error);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error('[Pubinfo Inspector] Failed to add WebSocket listener:', error);
|
|
87
|
+
return () => {};
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// 监听 WebSocket 连接状态变化
|
|
92
|
+
onConnectionChange(callback) {
|
|
93
|
+
if (!import.meta.hot) {
|
|
94
|
+
console.warn('[Pubinfo Inspector] HMR not available');
|
|
95
|
+
return () => {};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const listeners = [];
|
|
99
|
+
|
|
100
|
+
// 监听连接建立
|
|
101
|
+
const offConnect = this.on('vite:ws:connect', () => {
|
|
102
|
+
callback('connected');
|
|
103
|
+
});
|
|
104
|
+
listeners.push(offConnect);
|
|
105
|
+
|
|
106
|
+
// 监听连接断开
|
|
107
|
+
const offDisconnect = this.on('vite:ws:disconnect', () => {
|
|
108
|
+
callback('disconnected');
|
|
109
|
+
});
|
|
110
|
+
listeners.push(offDisconnect);
|
|
111
|
+
|
|
112
|
+
// 返回取消所有监听的函数
|
|
113
|
+
return () => {
|
|
114
|
+
listeners.forEach(off => off());
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// 获取 WebSocket 连接的详细信息
|
|
119
|
+
getConnectionDetails() {
|
|
120
|
+
const connection = this.getHMRConnection();
|
|
121
|
+
|
|
122
|
+
if (!connection || !connection.isAvailable) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 尝试获取更多连接详细信息
|
|
127
|
+
const details = {
|
|
128
|
+
state: connection.connectionState,
|
|
129
|
+
url: null,
|
|
130
|
+
protocol: null,
|
|
131
|
+
readyState: null,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
// 尝试从内部访问 WebSocket 实例
|
|
136
|
+
const transport = connection.client?.transport;
|
|
137
|
+
if (transport?.socket) {
|
|
138
|
+
details.url = transport.socket.url;
|
|
139
|
+
details.protocol = transport.socket.protocol;
|
|
140
|
+
details.readyState = transport.socket.readyState;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
// 静默处理错误,因为这些是内部 API
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return details;
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
// 测试 WebSocket 连接
|
|
151
|
+
async testConnection() {
|
|
152
|
+
if (!import.meta.hot) {
|
|
153
|
+
return { success: false, error: 'HMR not available' };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
// 发送一个测试事件
|
|
158
|
+
const testEventName = `pubinfo:test:${Date.now()}`;
|
|
159
|
+
let received = false;
|
|
160
|
+
|
|
161
|
+
// 监听响应
|
|
162
|
+
const off = this.on(`${testEventName}:response`, () => {
|
|
163
|
+
received = true;
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// 发送测试消息
|
|
167
|
+
this.send(testEventName, { timestamp: Date.now() });
|
|
168
|
+
|
|
169
|
+
// 等待响应(超时 5 秒)
|
|
170
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
171
|
+
|
|
172
|
+
off();
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
success: true,
|
|
176
|
+
connectionWorking: received,
|
|
177
|
+
details: this.getConnectionDetails(),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
return {
|
|
182
|
+
success: false,
|
|
183
|
+
error: error.message,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
// 性能监控
|
|
190
|
+
performance: {
|
|
191
|
+
mark: (name) => {
|
|
192
|
+
if (typeof performance !== 'undefined' && performance.mark) {
|
|
193
|
+
performance.mark(name);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
measure: (name, startMark, endMark) => {
|
|
197
|
+
if (typeof performance !== 'undefined' && performance.measure) {
|
|
198
|
+
try {
|
|
199
|
+
performance.measure(name, startMark, endMark);
|
|
200
|
+
const entries = performance.getEntriesByName(name);
|
|
201
|
+
return entries[entries.length - 1];
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
console.warn('Performance measurement failed:', e);
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// 导出默认对象
|
|
214
|
+
export default inspectorUtils;
|
|
215
|
+
|
|
216
|
+
// 全局访问接口 - 让其他模块可以访问 WebSocket 功能
|
|
217
|
+
if (typeof globalThis !== 'undefined') {
|
|
218
|
+
// 在全局对象上暴露 WebSocket 工具
|
|
219
|
+
globalThis.__PUBINFO_WEBSOCKET__ = {
|
|
220
|
+
// 发送消息
|
|
221
|
+
send: (event, data) => inspectorUtils.websocket.send(event, data),
|
|
222
|
+
|
|
223
|
+
// 监听事件
|
|
224
|
+
on: (event, callback) => inspectorUtils.websocket.on(event, callback),
|
|
225
|
+
|
|
226
|
+
// 获取连接信息
|
|
227
|
+
getConnection: () => inspectorUtils.websocket.getHMRConnection(),
|
|
228
|
+
|
|
229
|
+
// 获取连接详情
|
|
230
|
+
getDetails: () => inspectorUtils.websocket.getConnectionDetails(),
|
|
231
|
+
|
|
232
|
+
// 测试连接
|
|
233
|
+
test: () => inspectorUtils.websocket.testConnection(),
|
|
234
|
+
|
|
235
|
+
// 监听连接状态
|
|
236
|
+
onStateChange: callback => inspectorUtils.websocket.onConnectionChange(callback),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// HMR 支持 - 静默接受热更新,避免页面重新加载
|
|
241
|
+
if (import.meta.hot) {
|
|
242
|
+
// 静默接受热更新,不输出日志,避免噪音
|
|
243
|
+
import.meta.hot.accept(() => {
|
|
244
|
+
// 静默重新初始化全局接口,不输出任何日志
|
|
245
|
+
if (typeof globalThis !== 'undefined') {
|
|
246
|
+
globalThis.__PUBINFO_WEBSOCKET__ = {
|
|
247
|
+
send: (event, data) => inspectorUtils.websocket.send(event, data),
|
|
248
|
+
on: (event, callback) => inspectorUtils.websocket.on(event, callback),
|
|
249
|
+
getConnection: () => inspectorUtils.websocket.getHMRConnection(),
|
|
250
|
+
getDetails: () => inspectorUtils.websocket.getConnectionDetails(),
|
|
251
|
+
test: () => inspectorUtils.websocket.testConnection(),
|
|
252
|
+
onStateChange: callback => inspectorUtils.websocket.onConnectionChange(callback),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// HMR 数据持久化
|
|
258
|
+
import.meta.hot.dispose((data) => {
|
|
259
|
+
// 静默保存当前状态
|
|
260
|
+
data.connectionInfo = inspectorUtils.websocket.getConnectionDetails();
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// 静默从之前的状态恢复
|
|
264
|
+
if (import.meta.hot.data?.connectionInfo) {
|
|
265
|
+
// 静默恢复,不输出日志
|
|
266
|
+
}
|
|
267
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pubinfo/vite",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-rc.
|
|
4
|
+
"version": "2.0.0-rc.4",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -15,22 +15,23 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"vue": "^3.5.17"
|
|
19
|
-
"vue-i18n": "^10.0.7"
|
|
18
|
+
"vue": "^3.5.17"
|
|
20
19
|
},
|
|
21
20
|
"dependencies": {
|
|
22
|
-
"@pubinfo/unplugin-openapi": "^0.
|
|
21
|
+
"@pubinfo/unplugin-openapi": "^0.9.0",
|
|
23
22
|
"@vitejs/plugin-legacy": "^7.2.1",
|
|
24
23
|
"@vitejs/plugin-vue": "^6.0.0",
|
|
25
24
|
"@vitejs/plugin-vue-jsx": "^5.0.1",
|
|
26
25
|
"abort-controller": "^3.0.0",
|
|
27
26
|
"boxen": "^8.0.1",
|
|
28
27
|
"chalk": "^5.4.1",
|
|
28
|
+
"chokidar": "^4.0.1",
|
|
29
29
|
"consola": "^3.4.2",
|
|
30
30
|
"fast-glob": "^3.3.3",
|
|
31
31
|
"fs-extra": "^11.3.0",
|
|
32
32
|
"jszip": "^3.10.1",
|
|
33
33
|
"lodash-es": "^4.17.21",
|
|
34
|
+
"picomatch": "^4.0.3",
|
|
34
35
|
"rolldown-vite": "^7.1.2",
|
|
35
36
|
"terser": "^5.43.1",
|
|
36
37
|
"unocss": "^66.4.2",
|
|
@@ -48,8 +49,8 @@
|
|
|
48
49
|
"@types/fs-extra": "^11.0.4",
|
|
49
50
|
"@types/lodash-es": "^4.17.12",
|
|
50
51
|
"@types/node": "^24.0.10",
|
|
51
|
-
"
|
|
52
|
-
"vue
|
|
52
|
+
"@types/picomatch": "^4.0.2",
|
|
53
|
+
"vue": "^3.5.17"
|
|
53
54
|
},
|
|
54
55
|
"scripts": {
|
|
55
56
|
"dev": "tsdown --watch",
|