@pubinfo/vite 2.0.11 → 2.0.13

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
@@ -1,9 +1,31 @@
1
1
  import { UserConfig, UserConfigFnObject } from "rolldown-vite";
2
+ import * as vite_plugin_vue_devtools0 from "vite-plugin-vue-devtools";
3
+ import { VitePluginVueDevToolsOptions } from "vite-plugin-vue-devtools";
2
4
  import * as _pubinfo_unplugin_openapi0 from "@pubinfo/unplugin-openapi";
3
5
  import { Options } from "@pubinfo/unplugin-openapi";
4
6
  export * from "rolldown-vite";
5
7
  export * from "vite-plugin-fake-server/client";
6
8
 
9
+ //#region src/plugins/built-in/chrome-devtools.d.ts
10
+ /**
11
+ * Chrome DevTools 插件配置选项
12
+ */
13
+ interface ChromeDevtoolsOptions {
14
+ /** 是否启用插件 */
15
+ enabled?: boolean;
16
+ /** 自定义端口,如果不指定则自动分配 */
17
+ port?: number;
18
+ /** 是否自动注入调试脚本到页面 */
19
+ autoInject?: boolean;
20
+ /** DevTools 面板访问路径 */
21
+ panelPath?: string;
22
+ }
23
+ /**
24
+ * 创建 Chrome DevTools 插件
25
+ * @param options 插件配置选项
26
+ * @returns Vite 插件
27
+ */
28
+ //#endregion
7
29
  //#region src/plugins/built-in/inject-auto.d.ts
8
30
  interface InjectAutoOptions {
9
31
  id: string;
@@ -54,6 +76,12 @@ interface PubinfoConfig {
54
76
  openapi?: Options;
55
77
  /** `resolver` */
56
78
  resolver?: ResolverPluginOptions;
79
+ /** devtools */
80
+ devtools?: Omit<VitePluginVueDevToolsOptions, 'enabled'> & {
81
+ enabled?: boolean;
82
+ };
83
+ /** chrome devtools */
84
+ chromeDevtools?: ChromeDevtoolsOptions;
57
85
  /** `commitlint` */
58
86
  commitlint?: boolean | CommitlintOptions;
59
87
  }
@@ -72,6 +100,10 @@ declare function definePubinfoConfig(config: PubinfoConfig): {
72
100
  vite: UserConfigFnObject;
73
101
  openapi?: _pubinfo_unplugin_openapi0.Options;
74
102
  resolver?: ResolverPluginOptions;
103
+ devtools?: Omit<vite_plugin_vue_devtools0.VitePluginVueDevToolsOptions, "enabled"> & {
104
+ enabled?: boolean;
105
+ };
106
+ chromeDevtools?: ChromeDevtoolsOptions;
75
107
  commitlint?: boolean | CommitlintOptions;
76
108
  };
77
109
  /**
@@ -82,7 +114,11 @@ declare function defineModuleConfig(config: ModuleConfig): {
82
114
  moduleId: InjectAutoOptions["id"];
83
115
  openapi?: _pubinfo_unplugin_openapi0.Options;
84
116
  resolver?: ResolverPluginOptions;
117
+ devtools?: Omit<vite_plugin_vue_devtools0.VitePluginVueDevToolsOptions, "enabled"> & {
118
+ enabled?: boolean;
119
+ };
120
+ chromeDevtools?: ChromeDevtoolsOptions;
85
121
  commitlint?: boolean | CommitlintOptions;
86
122
  };
87
123
  //#endregion
88
- export { CommitlintOptions, ModuleConfig, PubinfoConfig, ResolverPluginOptions, defineModuleConfig, definePubinfoConfig };
124
+ export { ChromeDevtoolsOptions, CommitlintOptions, ModuleConfig, PubinfoConfig, ResolverPluginOptions, defineModuleConfig, definePubinfoConfig };
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ 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 boxen from "boxen";
10
+ import MagicString from "magic-string";
10
11
  import fg from "fast-glob";
11
12
  import { merge } from "lodash-es";
12
13
  import picomatch from "picomatch";
@@ -72,6 +73,209 @@ function getServerProxy(env, isProxy) {
72
73
  return serverProxy;
73
74
  }
74
75
 
76
+ //#endregion
77
+ //#region src/plugins/built-in/chrome-devtools.ts
78
+ /**
79
+ * Chii 服务管理器
80
+ */
81
+ var ChiiServiceManager = class {
82
+ port;
83
+ isStarted = false;
84
+ /**
85
+ * 启动 Chii 服务
86
+ * @param customPort 自定义端口
87
+ * @param vitePort Vite 开发服务器端口
88
+ * @param viteHost Vite 开发服务器主机
89
+ * @param panelPath DevTools 面板路径
90
+ * @returns 服务端口号
91
+ */
92
+ async start(customPort, vitePort, viteHost, panelPath) {
93
+ if (this.isStarted && this.port) return this.port;
94
+ try {
95
+ const { start } = await this.importChii();
96
+ const port = customPort || this.generatePort(vitePort);
97
+ start({ port });
98
+ this.port = port;
99
+ this.isStarted = true;
100
+ return port;
101
+ } catch (error) {
102
+ console.warn("[pubinfo][chrome-devtools] 启动 Chii 失败:", error);
103
+ return;
104
+ }
105
+ }
106
+ /**
107
+ * 获取服务端口
108
+ */
109
+ getPort() {
110
+ return this.port;
111
+ }
112
+ /**
113
+ * 检查服务是否已启动
114
+ */
115
+ isServiceStarted() {
116
+ return this.isStarted && !!this.port;
117
+ }
118
+ /**
119
+ * 生成可用端口
120
+ * @param vitePort Vite 端口
121
+ * @returns 生成的端口号
122
+ */
123
+ generatePort(vitePort) {
124
+ if (vitePort) return vitePort + 1e3;
125
+ return 9229 + Math.floor(Math.random() * 100);
126
+ }
127
+ /**
128
+ * 输出启动信息
129
+ * @param host 主机地址
130
+ * @param vitePort Vite 端口
131
+ * @param panelPath 面板路径
132
+ */
133
+ logStartupInfo(host, vitePort, panelPath) {
134
+ if (!this.port) return;
135
+ const panelUrl = `${`http://${host}:${vitePort}`}${panelPath}`;
136
+ const colorUrl = (url) => chalk.cyan(url.replace(/:(\d+)\//, (_, port) => `:${chalk.bold(port)}/`));
137
+ console.log(` ${chalk.green("➜")} ${chalk.bold("Chrome DevTools")}: ${chalk.green(`Open ${colorUrl(panelUrl)} as a separate window`)}`);
138
+ }
139
+ /**
140
+ * 动态导入 chii
141
+ */
142
+ async importChii() {
143
+ return await import(
144
+ /* @vite-ignore */
145
+ "chii"
146
+ );
147
+ }
148
+ };
149
+ /**
150
+ * DevTools 面板处理器
151
+ */
152
+ var DevToolsPanelHandler = class {
153
+ panelPath;
154
+ serviceManager;
155
+ constructor(panelPath, serviceManager) {
156
+ this.panelPath = panelPath;
157
+ this.serviceManager = serviceManager;
158
+ }
159
+ /**
160
+ * 创建面板访问中间件
161
+ */
162
+ createMiddleware(server) {
163
+ server.middlewares.use(async (req, res, next) => {
164
+ if (!this.isTargetPath(req.url)) return next();
165
+ const port = this.serviceManager.getPort();
166
+ if (!port) {
167
+ this.sendErrorResponse(res, "DevTools 后端服务未启动");
168
+ return;
169
+ }
170
+ try {
171
+ const devtoolsUrl = await this.getDevToolsUrl(port);
172
+ this.sendRedirectResponse(res, devtoolsUrl);
173
+ } catch (error) {
174
+ console.warn("[pubinfo][chrome-devtools] 获取 DevTools URL 失败:", error);
175
+ this.sendRedirectResponse(res, `http://127.0.0.1:${port}/`);
176
+ }
177
+ });
178
+ }
179
+ /**
180
+ * 检查是否为目标路径
181
+ */
182
+ isTargetPath(url) {
183
+ if (!url) return false;
184
+ return url === this.panelPath || url === `${this.panelPath}/`;
185
+ }
186
+ /**
187
+ * 获取 DevTools URL
188
+ */
189
+ async getDevToolsUrl(port) {
190
+ const firstTarget = (await (await fetch(`http://127.0.0.1:${port}/targets`)).json())?.targets?.[0];
191
+ if (firstTarget) {
192
+ const wsId = Math.random().toString(36).slice(2, 10);
193
+ return `http://127.0.0.1:${port}/front_end/chii_app.html?ws=${encodeURIComponent(`127.0.0.1:${port}/client/${wsId}?target=${firstTarget.id}`)}&rtc=false`;
194
+ }
195
+ return `http://127.0.0.1:${port}/`;
196
+ }
197
+ /**
198
+ * 发送错误响应
199
+ */
200
+ sendErrorResponse(res, message) {
201
+ res.statusCode = 503;
202
+ res.end(message);
203
+ }
204
+ /**
205
+ * 发送重定向响应
206
+ */
207
+ sendRedirectResponse(res, location) {
208
+ res.statusCode = 302;
209
+ res.setHeader("Location", location);
210
+ res.end();
211
+ }
212
+ };
213
+ /**
214
+ * HTML 注入器
215
+ */
216
+ var HtmlInjector = class {
217
+ serviceManager;
218
+ constructor(serviceManager) {
219
+ this.serviceManager = serviceManager;
220
+ }
221
+ /**
222
+ * 注入调试脚本到 HTML
223
+ */
224
+ injectScript(html) {
225
+ const port = this.serviceManager.getPort();
226
+ if (!port) return html;
227
+ const injectedMarker = `//__chrome_devtools_target_${port}`;
228
+ if (html.includes(injectedMarker)) return html;
229
+ const scriptTag = this.createScriptTag(port, injectedMarker);
230
+ return this.insertScriptTag(html, scriptTag);
231
+ }
232
+ /**
233
+ * 创建脚本标签
234
+ */
235
+ createScriptTag(port, marker) {
236
+ return `<script>${marker}<\/script>\n<script src="http://127.0.0.1:${port}/target.js" data-pubinfo-devtools="chrome"><\/script>`;
237
+ }
238
+ /**
239
+ * 插入脚本标签到 HTML
240
+ */
241
+ insertScriptTag(html, scriptTag) {
242
+ if (/<head[\s\S]*?>/i.test(html)) return html.replace(/<head([\s\S]*?)>/i, (match) => `${match}\n${scriptTag}`);
243
+ return html.replace(/<body(.*?)>/i, (match) => `${match}\n${scriptTag}`);
244
+ }
245
+ };
246
+ /**
247
+ * 创建 Chrome DevTools 插件
248
+ * @param options 插件配置选项
249
+ * @returns Vite 插件
250
+ */
251
+ function createChromeDevtools(options = {}) {
252
+ const { enabled = true, port, autoInject = true, panelPath = "/__chrome_devtools" } = options;
253
+ if (!enabled) return null;
254
+ const serviceManager = new ChiiServiceManager();
255
+ const panelHandler = new DevToolsPanelHandler(panelPath, serviceManager);
256
+ const htmlInjector = new HtmlInjector(serviceManager);
257
+ return {
258
+ name: "pubinfo:chrome-devtools",
259
+ apply: "serve",
260
+ enforce: "post",
261
+ async configureServer(server) {
262
+ const vitePort = server.config.server.port || 5173;
263
+ const viteHost = typeof server.config.server.host === "string" ? server.config.server.host : "localhost";
264
+ await serviceManager.start(port, vitePort, viteHost, panelPath);
265
+ panelHandler.createMiddleware(server);
266
+ const _printUrls = server.printUrls;
267
+ server.printUrls = () => {
268
+ _printUrls();
269
+ serviceManager.logStartupInfo(viteHost, vitePort, panelPath);
270
+ };
271
+ },
272
+ transformIndexHtml(html) {
273
+ if (!autoInject) return html;
274
+ return htmlInjector.injectScript(html);
275
+ }
276
+ };
277
+ }
278
+
75
279
  //#endregion
76
280
  //#region src/plugins/built-in/info.ts
77
281
  var Ctx$1 = class {
@@ -134,15 +338,22 @@ function createInjectAuto(options) {
134
338
  else if (typeof lib.entry === "object") entryFiles = Object.values(lib.entry).map(toAbs);
135
339
  },
136
340
  transform(code, _id) {
137
- if (entryFiles.includes(_id)) return `
341
+ if (entryFiles.includes(_id)) {
342
+ const s = new MagicString(code);
343
+ const injectCode = `
138
344
  import { defineRouteModule, defineIconModule } from 'pubinfo';
139
345
  import modules from 'virtual:pubinfo-resolver';
140
346
 
141
347
  defineRouteModule('${id}', modules.pages);
142
348
  defineIconModule('${id}', modules.icons);
143
349
 
144
- ${code}
145
350
  `;
351
+ s.prepend(injectCode);
352
+ return {
353
+ code: s.toString(),
354
+ map: s.generateMap({ hires: true })
355
+ };
356
+ }
146
357
  }
147
358
  };
148
359
  }
@@ -226,14 +437,13 @@ function libResolverPlugin(options) {
226
437
  files: []
227
438
  };
228
439
  const base = getPatternBase(pattern);
229
- const imports = files.map((file) => {
230
- const absPath = normalizePath$1(file);
231
- const relToBase = normalizePath$1(relative(resolve(base), file));
232
- return `"${posix.join(base, relToBase)}": () => import("${absPath}")`;
233
- }).join(",\n");
234
440
  return {
235
441
  key,
236
- content: `"${key}": {\n${imports}\n }`,
442
+ content: `"${key}": {\n${files.map((file) => {
443
+ const absPath = normalizePath$1(file);
444
+ const relToBase = normalizePath$1(relative(resolve(base), file));
445
+ return `"${posix.join(base, relToBase)}": () => import("${absPath}")`;
446
+ }).join(",\n")}\n }`,
237
447
  files
238
448
  };
239
449
  } catch (error) {
@@ -300,10 +510,12 @@ function createVirtualInspectorPlugin(options = {}) {
300
510
  });
301
511
  },
302
512
  async resolveId(importee) {
513
+ if (config?.command !== "serve") return null;
303
514
  if (importee === virtualModuleId) return resolve(inspectorPath, "load.js");
304
515
  return null;
305
516
  },
306
517
  async load(id) {
518
+ if (config?.command !== "serve") return null;
307
519
  if (id.includes("load.js") && id.includes(inspectorPath)) {
308
520
  if (!enabled) return "export default {};";
309
521
  const filePath = resolve(inspectorPath, "load.js");
@@ -316,7 +528,7 @@ function createVirtualInspectorPlugin(options = {}) {
316
528
  return null;
317
529
  },
318
530
  transformIndexHtml(html) {
319
- if (!enabled) return;
531
+ if (!enabled || config?.command !== "serve") return;
320
532
  return {
321
533
  html,
322
534
  tags: [{
@@ -474,9 +686,8 @@ function createInjectCSS() {
474
686
 
475
687
  //#endregion
476
688
  //#region src/plugins/intergrations/inspector.ts
477
- function createInspector(env) {
478
- const { VITE_APP_INSPECTOR } = env;
479
- if (VITE_APP_INSPECTOR && VITE_APP_INSPECTOR === "true") return VueDevTools();
689
+ function createInspector(devtoolsConfig) {
690
+ if (devtoolsConfig?.enabled) return VueDevTools({ ...devtoolsConfig });
480
691
  else return null;
481
692
  }
482
693
 
@@ -527,7 +738,8 @@ function createVitePlugins(viteEnv, isBuild = false, config, type) {
527
738
  createUnocss(),
528
739
  createIcons(),
529
740
  createMock(viteEnv, isBuild),
530
- createInspector(viteEnv),
741
+ createInspector(config.devtools),
742
+ createChromeDevtools(config.chromeDevtools),
531
743
  createOpenAPI(config.openapi),
532
744
  createLibResolver(config.resolver),
533
745
  createAppInfo(),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pubinfo/vite",
3
3
  "type": "module",
4
- "version": "2.0.11",
4
+ "version": "2.0.13",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -28,12 +28,14 @@
28
28
  "abort-controller": "^3.0.0",
29
29
  "boxen": "^8.0.1",
30
30
  "chalk": "^5.4.1",
31
+ "chii": "^1.15.5",
31
32
  "consola": "^3.4.2",
32
33
  "dayjs": "^1.11.13",
33
34
  "fast-glob": "^3.3.3",
34
35
  "fs-extra": "^11.3.0",
35
36
  "jszip": "^3.10.1",
36
37
  "lodash-es": "^4.17.21",
38
+ "magic-string": "^0.30.19",
37
39
  "picomatch": "^4.0.3",
38
40
  "pkg-types": "^2.3.0",
39
41
  "rolldown-vite": "^7.1.2",