@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 CHANGED
@@ -26,10 +26,6 @@ interface ModuleEntries {
26
26
  interface ResolverPluginOptions {
27
27
  /** 入口配置 */
28
28
  entries: ModuleEntries;
29
- /** 启用缓存优化 */
30
- cache?: boolean;
31
- /** 最大缓存大小 */
32
- maxCacheSize?: number;
33
29
  }
34
30
  //#endregion
35
31
  //#region src/interface.d.ts
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 autoImport({
72
- imports: [
73
- "vue",
74
- "vue-router",
75
- "pinia",
76
- { pubinfo: ["useAuth"] }
77
- ],
78
- ignore: ["h"],
79
- dts: "./.pubinfo/auto-imports.d.ts",
80
- resolvers: [AntDesignVueResolver(), IconsResolver({ prefix: "i" })]
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
- const components$1 = [
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 dts({
142
- clearPureImport: false,
143
- exclude: ["tests/**/*"]
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
- const enableCache = options.cache ?? true;
237
- const maxCacheSize = options.maxCacheSize ?? 50;
238
- const cache = /* @__PURE__ */ new Map();
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
- if (!enableCache) cache.clear();
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
- const configHash = createHash("md5").update(JSON.stringify(options.entries)).digest("hex");
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
- const relPath = posix.join(base, relToBase);
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
- entries: {
331
- icons: "src/assets/icons/**/*",
332
- layouts: "src/layouts/*.vue",
333
- pages: "src/views/**/*.vue"
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
- const vitePlugins = [
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
- const serverProxy = getServerProxy(env, !isBuild && VITE_OPEN_PROXY === "true");
397
- const applicationConfig = {
456
+ return {
398
457
  base: "./",
399
458
  server: {
400
459
  open: true,
401
460
  host: true,
402
- proxy: serverProxy,
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
- const applicationConfig = {
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.2",
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.8.4",
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
- "vue": "^3.5.17",
52
- "vue-i18n": "^10.0.7"
52
+ "@types/picomatch": "^4.0.2",
53
+ "vue": "^3.5.17"
53
54
  },
54
55
  "scripts": {
55
56
  "dev": "tsdown --watch",