vite-check-multiple-dom 0.1.0 → 0.1.1-beta.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DqgTaEhZ.d.cts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;AAUkB;AAuBK,KAvBlB,aAAA,GAuFmB;EAAoC,EAAA,EAAA;IAUjC,IAAA,EAAA,CAAA,OAAA,EAAA;MAYC,IAAA,EAAA,OAAA;MAAa,GAAA,EAAA;;;;;;;;;;;;;;;;;KAtFpC,kBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgEmB,oCAAA,CAAA;;;;;yBAUG;;;;;0BAYC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DyJ9Q1c6.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;AAUkB;AAuBK,KAvBlB,aAAA,GAuFmB;EAAoC,EAAA,EAAA;IAUjC,IAAA,EAAA,CAAA,OAAA,EAAA;MAYC,IAAA,EAAA,OAAA;MAAa,GAAA,EAAA;;;;;;;;;;;;;;;;;KAtFpC,kBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgEmB,oCAAA,CAAA;;;;;yBAUG;;;;;0BAYC"}
package/dist/index.cjs CHANGED
@@ -1,5 +1,35 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ //#endregion
1
28
  let node_url = require("node:url");
2
29
  let node_fs = require("node:fs");
30
+ node_fs = __toESM(node_fs);
31
+ let path = require("path");
32
+ path = __toESM(path);
3
33
  let node_path = require("node:path");
4
34
 
5
35
  //#region src/i18n.ts
@@ -55,11 +85,11 @@ function getMessageHeader(lang) {
55
85
  * 发送错误覆盖层到客户端(优先定向发送,避免首屏时广播命中不到当前 client)
56
86
  */
57
87
  function sendErrorOverlay(args) {
58
- const { server, message, lang, client } = args;
88
+ const { server, message, lang, client, needMergeMessage } = args;
59
89
  const payload = {
60
90
  type: "error",
61
91
  err: {
62
- message: getMessageHeader(lang),
92
+ message: needMergeMessage ? `${getMessageHeader(lang)}\n${message}` : getMessageHeader(lang),
63
93
  stack: message
64
94
  }
65
95
  };
@@ -90,10 +120,14 @@ function sendErrorOverlay(args) {
90
120
  */
91
121
  function vitePluginVueTransitionRootValidator() {
92
122
  let resolved;
123
+ let needMergeMessage;
93
124
  return {
94
125
  name: "vite-plugin-vue-transition-root-validator",
95
126
  configResolved(config) {
96
127
  resolved = config;
128
+ const viteVersion = config.version;
129
+ const viteMajorVersion = viteVersion ? parseInt(viteVersion.split(".")[0], 10) : 6;
130
+ needMergeMessage = isNaN(viteMajorVersion) || viteMajorVersion < 7;
97
131
  },
98
132
  configureServer(server) {
99
133
  if (resolved.command !== "serve") return;
@@ -111,7 +145,8 @@ function vitePluginVueTransitionRootValidator() {
111
145
  server,
112
146
  message: payload.message,
113
147
  lang: effectiveLang,
114
- client
148
+ client,
149
+ needMergeMessage
115
150
  });
116
151
  client?.send?.("vite-plugin-vue-transition-root-validator:ack", { key });
117
152
  });
@@ -137,12 +172,27 @@ export { setupVueRootValidator };
137
172
  }
138
173
  return null;
139
174
  },
140
- buildEnd(err) {
141
- if (err) return;
142
- if (!(resolved.plugins || []).some((p) => p.name === "svgBuilder")) {
143
- const outDir = resolved.build?.outDir ?? "dist";
144
- const indexHtmlPath = (0, node_path.resolve)((0, node_path.resolve)(resolved.root ?? process.cwd(), outDir), "index.html");
145
- if ((0, node_fs.existsSync)(indexHtmlPath)) (0, node_fs.writeFileSync)(indexHtmlPath, "");
175
+ closeBundle(options) {
176
+ console.log("进入closeBundle", options);
177
+ try {
178
+ const outDir = options.config.build.outDir;
179
+ const htmlFilePath = path.default.resolve(process.cwd(), outDir, "index.html");
180
+ if (!node_fs.default.existsSync(htmlFilePath)) {
181
+ console.log(`[空HTML插件] 未找到 HTML 文件:${htmlFilePath}`);
182
+ return;
183
+ }
184
+ const plugins = resolved.plugins || [];
185
+ console.log("plugins", plugins);
186
+ if (!plugins.some((p) => p.name === "svgBuilder")) {
187
+ const outDir$1 = resolved.build?.outDir ?? "dist";
188
+ (0, node_path.resolve)((0, node_path.resolve)(resolved.root ?? process.cwd(), outDir$1), "index.html");
189
+ node_fs.default.writeFileSync(htmlFilePath, "", "utf-8");
190
+ console.log(`[空HTML插件] 已成功将 HTML 文件置空:${htmlFilePath}`);
191
+ return;
192
+ }
193
+ console.log(`[空HTML插件] 不满足置空条件,跳过 HTML 置空`);
194
+ } catch (error) {
195
+ console.error(`[空HTML插件] 操作失败:`, error.message);
146
196
  }
147
197
  }
148
198
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/i18n.ts","../src/index.ts"],"sourcesContent":["import type { Lang } from './types.ts';\n\nexport type TransitionRootMessageContext = {\n file?: string;\n url?: string;\n routeKey?: string;\n component?: string;\n};\n\nconst translations = {\n zh: {\n messageHeader: '[vite-plugin-vue-transition-root-validator] 检测到 Vue Transition 多根节点错误',\n setupInstructions: `\n如何在项目中启用此插件:\n\n1. 在 vite.config.ts 中添加插件:\n import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n\n plugins: [\n vitePluginVueTransitionRootValidator()\n ]\n\n2. 在 src/main.ts 中初始化:\n import { setupVueRootValidator } from 'virtual:vue-transition-root-validator';\n\n const app = createApp(App);\n setupVueRootValidator(app, { lang: 'zh' });\n app.mount('#app');\n`\n },\n en: {\n messageHeader: '[vite-plugin-vue-transition-root-validator] Vue Transition Multiple Root Nodes Error',\n setupInstructions: `\nHow to enable this plugin in your project:\n\n1. Add plugin in vite.config.ts:\n import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n\n plugins: [\n vitePluginVueTransitionRootValidator()\n ]\n\n2. Initialize in src/main.ts:\n import { setupVueRootValidator } from 'virtual:vue-transition-root-validator';\n\n const app = createApp(App);\n setupVueRootValidator(app, { lang: 'en' });\n app.mount('#app');\n`\n }\n};\n\nexport function formatTransitionRootMessage(lang: Lang, ctx: TransitionRootMessageContext): string {\n if (lang === 'zh') {\n const title = 'Vue <Transition> 要求插槽内容具有单一的“元素根节点”。';\n const lines: string[] = [];\n lines.push(title);\n\n if (ctx.file) lines.push(`\\n文件: ${ctx.file}`);\n if (ctx.url) lines.push(`URL: ${ctx.url}`);\n\n const meta: string[] = [];\n if (ctx.component) meta.push(`component=${ctx.component}`);\n if (ctx.routeKey) meta.push(`key=${ctx.routeKey}`);\n if (meta.length) lines.push(`上下文: ${meta.join(' ')}`);\n\n lines.push(\n '\\n如何修复:\\n' +\n `- 在${ctx.file ? `文件 ${ctx.file}` : '该组件'}的 <template> 最外层添加一个容器标签(如 <div> / <main>),把所有内容包起来,确保最终只渲染出一个根“标签元素”。\\n` +\n '- 根节点不能是多个并列元素(Fragment/多根),也不能是纯文本或注释。\\n' +\n '- 如果根部使用了 v-if / v-else,确保每个分支都只渲染一个根标签元素。'\n );\n\n lines.push(\n '\\n为什么会这样:\\n' +\n 'Vue 的 <Transition> 需要把过渡 class 应用在一个真实的 DOM 元素上;' +\n '当插槽内容渲染出的根节点不是“单一元素”(例如 Fragment、多根、纯文本或注释)时,就无法执行进入/离开过渡。'\n );\n\n lines.push('\\n相关文档:\\nhttps://cn.vuejs.org/guide/built-ins/transition#the-transition-component');\n\n return lines.join('\\n');\n }\n\n // English\n const title = 'Vue <Transition> requires a single element root node in its slot.';\n const lines: string[] = [];\n lines.push(title);\n\n if (ctx.file) lines.push(`\\nFile: ${ctx.file}`);\n if (ctx.url) lines.push(`URL: ${ctx.url}`);\n\n const meta: string[] = [];\n if (ctx.component) meta.push(`component=${ctx.component}`);\n if (ctx.routeKey) meta.push(`key=${ctx.routeKey}`);\n if (meta.length) lines.push(`Context: ${meta.join(' ')}`);\n\n lines.push(\n '\\nHow to fix:\\n' +\n `- In the <template> of ${ctx.file ? `file ${ctx.file}` : 'this component'}, wrap everything with a single container element (e.g. <div> / <main>), so the final render has exactly one root *element*.\\n` +\n '- The root cannot be a Fragment (multiple siblings), plain text, or a comment.\\n' +\n '- If you use v-if / v-else at the root, ensure each branch renders exactly one root element.'\n );\n\n lines.push(\n '\\nWhy this happens:\\n' +\n 'Vue <Transition> needs to apply transition classes to a real DOM element. ' +\n 'If the slot content renders a non-element root (Fragment/multiple roots/text/comment), Vue cannot animate it.'\n );\n\n lines.push('\\nDocs:\\nhttps://cn.vuejs.org/guide/built-ins/transition#the-transition-component');\n\n return lines.join('\\n');\n}\n\nexport function getMessageHeader(lang: Lang): string {\n return translations[lang].messageHeader;\n}\n\nexport function getSetupInstructions(lang: Lang): string {\n return translations[lang].setupInstructions;\n}\n","import { fileURLToPath } from 'node:url';\nimport { existsSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { Lang } from './types.ts';\nimport { getMessageHeader } from './i18n.ts';\n\n/**\n * Vite DevServer 类型(精简版)\n */\ntype DevServerLike = {\n ws: {\n send: (payload: { type: 'error'; err: { message: string; stack?: string } }) => void;\n on: (event: string, listener: (payload: any, client: any) => void) => void;\n };\n config: {\n logger: {\n warn: (msg: string) => void;\n info: (msg: string) => void;\n };\n };\n};\n\ntype DevClientLike = {\n send?: {\n (payload: { type: 'error'; err: { message: string; stack?: string } }): void;\n (event: string, payload?: any): void;\n };\n};\n\n/**\n * Vite ResolvedConfig 类型(精简版)\n */\ntype ResolvedConfigLike = {\n command: 'serve' | 'build' | string;\n};\n\n/**\n * 发送错误覆盖层到客户端(优先定向发送,避免首屏时广播命中不到当前 client)\n */\nfunction sendErrorOverlay(args: { server: DevServerLike; message: string; lang: Lang; client?: DevClientLike }) {\n const { server, message, lang, client } = args;\n const payload = {\n type: 'error',\n err: {\n message: getMessageHeader(lang),\n stack: message\n }\n } as const;\n\n if (client?.send) {\n client.send(payload);\n return;\n }\n\n server.ws.send(payload);\n}\n\n/**\n * 客户端上报的消息载荷\n */\ntype ClientReportPayload = {\n message: string;\n /** 用于 ACK 去重/确认(客户端可不传,服务端会回退使用 message 截断值) */\n key?: string;\n /** 客户端运行时语言(推荐从 main.ts 传入并上报),用于决定 overlay header 语言 */\n lang?: Lang;\n};\n\n/**\n * Vite 插件:Vue Root Validator\n *\n * 用于检测 Vue 组件在 <Transition> 内渲染时的多根节点问题\n *\n * @returns Vite 插件对象\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n *\n * export default defineConfig({\n * plugins: [\n * vitePluginVueTransitionRootValidator()\n * ]\n * });\n * ```\n */\nexport default function vitePluginVueTransitionRootValidator() {\n let resolved: ResolvedConfigLike & { plugins?: any[]; root?: string; build?: { outDir?: string } };\n\n return {\n name: 'vite-plugin-vue-transition-root-validator',\n\n /**\n * 保存解析后的配置\n */\n configResolved(config: any) {\n resolved = config;\n },\n\n /**\n * 配置开发服务器\n * 监听客户端上报的警告消息,并通过 error overlay 显示\n */\n configureServer(server: DevServerLike) {\n if (resolved.command !== 'serve') return;\n\n // 用于去重,避免同一客户端重复发送相同消息\n const lastByClient = new WeakMap<object, string>();\n\n // 监听客户端上报的警告\n server.ws.on('vite-plugin-vue-transition-root-validator:vue-warn', (payload: ClientReportPayload, client: object) => {\n if (!payload?.message) return;\n\n // 去重处理\n const key = payload.key ?? payload.message.slice(0, 800);\n const prev = lastByClient.get(client as unknown as object);\n if (prev === key) {\n // 仍然回 ACK,避免客户端重试积压\n (client as any as DevClientLike)?.send?.('vite-plugin-vue-transition-root-validator:ack', { key });\n return;\n }\n lastByClient.set(client as unknown as object, key);\n\n const effectiveLang: Lang = payload.lang ?? 'en';\n\n // 发送错误覆盖层\n sendErrorOverlay({\n server,\n message: payload.message,\n lang: effectiveLang,\n client: client as any as DevClientLike\n });\n\n // 回 ACK,通知客户端该消息已被处理(用于清理重试队列)\n (client as any as DevClientLike)?.send?.('vite-plugin-vue-transition-root-validator:ack', { key });\n });\n },\n\n /**\n * 解析虚拟模块\n * 处理 'virtual:vue-transition-root-validator' 模块的导入\n */\n resolveId(id: string) {\n if (id === 'virtual:vue-transition-root-validator') {\n // 返回一个虚拟模块 ID,加上 \\0 前缀表示这是一个虚拟模块\n return '\\0virtual:vue-transition-root-validator';\n }\n return null;\n },\n\n /**\n * 加载虚拟模块\n * 返回虚拟模块的代码内容\n */\n load(id: string) {\n if (id === '\\0virtual:vue-transition-root-validator') {\n const clientEntryTs = fileURLToPath(new URL('./client.ts', import.meta.url));\n const clientEntryJs = fileURLToPath(new URL('./client.js', import.meta.url));\n const clientEntry = existsSync(clientEntryTs) ? clientEntryTs : clientEntryJs;\n const clientUrl = `/@fs/${clientEntry.replace(/\\\\/g, '/')}`;\n\n // 返回虚拟模块代码:重新导出 client.ts 的函数\n return `\n// 虚拟模块:vue-transition-root-validator\n// 此模块由 vite-plugin-vue-transition-root-validator 插件自动生成\n\nimport { setupVueRootValidator } from ${JSON.stringify(clientUrl)};\n\n// 重新导出函数\nexport { setupVueRootValidator };\n`;\n }\n return null;\n },\n\n buildEnd(err?: Error) {\n if (err) return;\n\n const plugins = resolved.plugins || [];\n const hasSvgBuilder = plugins.some((p: any) => p.name === 'svgBuilder');\n\n if (!hasSvgBuilder) {\n const outDir = resolved.build?.outDir ?? 'dist';\n const root = resolved.root ?? process.cwd();\n const distDir = resolve(root, outDir);\n const indexHtmlPath = resolve(distDir, 'index.html');\n\n if (existsSync(indexHtmlPath)) {\n writeFileSync(indexHtmlPath, '');\n }\n }\n }\n };\n}\n\n\n"],"mappings":";;;;;AASA,MAAM,eAAe;CACnB,IAAI;EACF,eAAe;EACf,mBAAmB;;;;;;;;;;;;;;;;;EAiBpB;CACD,IAAI;EACF,eAAe;EACf,mBAAmB;;;;;;;;;;;;;;;;;EAiBpB;CACF;AAiED,SAAgB,iBAAiB,MAAoB;AACnD,QAAO,aAAa,MAAM;;;;;;;;AC7E5B,SAAS,iBAAiB,MAAsF;CAC9G,MAAM,EAAE,QAAQ,SAAS,MAAM,WAAW;CAC1C,MAAM,UAAU;EACd,MAAM;EACN,KAAK;GACH,SAAS,iBAAiB,KAAK;GAC/B,OAAO;GACR;EACF;AAED,KAAI,QAAQ,MAAM;AAChB,SAAO,KAAK,QAAQ;AACpB;;AAGF,QAAO,GAAG,KAAK,QAAQ;;;;;;;;;;;;;;;;;;;;;AAiCzB,SAAwB,uCAAuC;CAC7D,IAAI;AAEJ,QAAO;EACL,MAAM;EAKN,eAAe,QAAa;AAC1B,cAAW;;EAOb,gBAAgB,QAAuB;AACrC,OAAI,SAAS,YAAY,QAAS;GAGlC,MAAM,+BAAe,IAAI,SAAyB;AAGlD,UAAO,GAAG,GAAG,uDAAuD,SAA8B,WAAmB;AACnH,QAAI,CAAC,SAAS,QAAS;IAGvB,MAAM,MAAM,QAAQ,OAAO,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAExD,QADa,aAAa,IAAI,OAA4B,KAC7C,KAAK;AAEhB,KAAC,QAAiC,OAAO,iDAAiD,EAAE,KAAK,CAAC;AAClG;;AAEF,iBAAa,IAAI,QAA6B,IAAI;IAElD,MAAM,gBAAsB,QAAQ,QAAQ;AAG5C,qBAAiB;KACf;KACA,SAAS,QAAQ;KACjB,MAAM;KACE;KACT,CAAC;AAGF,IAAC,QAAiC,OAAO,iDAAiD,EAAE,KAAK,CAAC;KAClG;;EAOJ,UAAU,IAAY;AACpB,OAAI,OAAO,wCAET,QAAO;AAET,UAAO;;EAOT,KAAK,IAAY;AACf,OAAI,OAAO,2CAA2C;IACpD,MAAM,4CAA8B,IAAI,IAAI,6DAA+B,CAAC;IAC5E,MAAM,4CAA8B,IAAI,IAAI,6DAA+B,CAAC;IAE5E,MAAM,YAAY,iCADa,cAAc,GAAG,gBAAgB,eAC1B,QAAQ,OAAO,IAAI;AAGzD,WAAO;;;;wCAIyB,KAAK,UAAU,UAAU,CAAC;;;;;;AAM5D,UAAO;;EAGT,SAAS,KAAa;AACpB,OAAI,IAAK;AAKT,OAAI,EAHY,SAAS,WAAW,EAAE,EACR,MAAM,MAAW,EAAE,SAAS,aAAa,EAEnD;IAClB,MAAM,SAAS,SAAS,OAAO,UAAU;IAGzC,MAAM,8DAFO,SAAS,QAAQ,QAAQ,KAAK,EACb,OAAO,EACE,aAAa;AAEpD,gCAAe,cAAc,CAC3B,4BAAc,eAAe,GAAG;;;EAIvC"}
1
+ {"version":3,"file":"index.cjs","names":["fs","outDir"],"sources":["../src/i18n.ts","../src/index.ts"],"sourcesContent":["import type { Lang } from './types.ts';\n\nexport type TransitionRootMessageContext = {\n file?: string;\n url?: string;\n routeKey?: string;\n component?: string;\n};\n\nconst translations = {\n zh: {\n messageHeader: '[vite-plugin-vue-transition-root-validator] 检测到 Vue Transition 多根节点错误',\n setupInstructions: `\n如何在项目中启用此插件:\n\n1. 在 vite.config.ts 中添加插件:\n import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n\n plugins: [\n vitePluginVueTransitionRootValidator()\n ]\n\n2. 在 src/main.ts 中初始化:\n import { setupVueRootValidator } from 'virtual:vue-transition-root-validator';\n\n const app = createApp(App);\n setupVueRootValidator(app, { lang: 'zh' });\n app.mount('#app');\n`\n },\n en: {\n messageHeader: '[vite-plugin-vue-transition-root-validator] Vue Transition Multiple Root Nodes Error',\n setupInstructions: `\nHow to enable this plugin in your project:\n\n1. Add plugin in vite.config.ts:\n import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n\n plugins: [\n vitePluginVueTransitionRootValidator()\n ]\n\n2. Initialize in src/main.ts:\n import { setupVueRootValidator } from 'virtual:vue-transition-root-validator';\n\n const app = createApp(App);\n setupVueRootValidator(app, { lang: 'en' });\n app.mount('#app');\n`\n }\n};\n\nexport function formatTransitionRootMessage(lang: Lang, ctx: TransitionRootMessageContext): string {\n if (lang === 'zh') {\n const title = 'Vue <Transition> 要求插槽内容具有单一的“元素根节点”。';\n const lines: string[] = [];\n lines.push(title);\n\n if (ctx.file) lines.push(`\\n文件: ${ctx.file}`);\n if (ctx.url) lines.push(`URL: ${ctx.url}`);\n\n const meta: string[] = [];\n if (ctx.component) meta.push(`component=${ctx.component}`);\n if (ctx.routeKey) meta.push(`key=${ctx.routeKey}`);\n if (meta.length) lines.push(`上下文: ${meta.join(' ')}`);\n\n lines.push(\n '\\n如何修复:\\n' +\n `- 在${ctx.file ? `文件 ${ctx.file}` : '该组件'}的 <template> 最外层添加一个容器标签(如 <div> / <main>),把所有内容包起来,确保最终只渲染出一个根“标签元素”。\\n` +\n '- 根节点不能是多个并列元素(Fragment/多根),也不能是纯文本或注释。\\n' +\n '- 如果根部使用了 v-if / v-else,确保每个分支都只渲染一个根标签元素。'\n );\n\n lines.push(\n '\\n为什么会这样:\\n' +\n 'Vue 的 <Transition> 需要把过渡 class 应用在一个真实的 DOM 元素上;' +\n '当插槽内容渲染出的根节点不是“单一元素”(例如 Fragment、多根、纯文本或注释)时,就无法执行进入/离开过渡。'\n );\n\n lines.push('\\n相关文档:\\nhttps://cn.vuejs.org/guide/built-ins/transition#the-transition-component');\n\n return lines.join('\\n');\n }\n\n // English\n const title = 'Vue <Transition> requires a single element root node in its slot.';\n const lines: string[] = [];\n lines.push(title);\n\n if (ctx.file) lines.push(`\\nFile: ${ctx.file}`);\n if (ctx.url) lines.push(`URL: ${ctx.url}`);\n\n const meta: string[] = [];\n if (ctx.component) meta.push(`component=${ctx.component}`);\n if (ctx.routeKey) meta.push(`key=${ctx.routeKey}`);\n if (meta.length) lines.push(`Context: ${meta.join(' ')}`);\n\n lines.push(\n '\\nHow to fix:\\n' +\n `- In the <template> of ${ctx.file ? `file ${ctx.file}` : 'this component'}, wrap everything with a single container element (e.g. <div> / <main>), so the final render has exactly one root *element*.\\n` +\n '- The root cannot be a Fragment (multiple siblings), plain text, or a comment.\\n' +\n '- If you use v-if / v-else at the root, ensure each branch renders exactly one root element.'\n );\n\n lines.push(\n '\\nWhy this happens:\\n' +\n 'Vue <Transition> needs to apply transition classes to a real DOM element. ' +\n 'If the slot content renders a non-element root (Fragment/multiple roots/text/comment), Vue cannot animate it.'\n );\n\n lines.push('\\nDocs:\\nhttps://cn.vuejs.org/guide/built-ins/transition#the-transition-component');\n\n return lines.join('\\n');\n}\n\nexport function getMessageHeader(lang: Lang): string {\n return translations[lang].messageHeader;\n}\n\nexport function getSetupInstructions(lang: Lang): string {\n return translations[lang].setupInstructions;\n}\n","import { fileURLToPath } from 'node:url';\nimport fs, { existsSync } from 'node:fs';\nimport path from 'path';\nimport { resolve } from 'node:path';\nimport type { Lang } from './types.ts';\nimport { getMessageHeader } from './i18n.ts';\n\n/**\n * Vite DevServer 类型(精简版)\n */\ntype DevServerLike = {\n ws: {\n send: (payload: { type: 'error'; err: { message: string; stack?: string } }) => void;\n on: (event: string, listener: (payload: any, client: any) => void) => void;\n };\n config: {\n logger: {\n warn: (msg: string) => void;\n info: (msg: string) => void;\n };\n };\n};\n\ntype DevClientLike = {\n send?: {\n (payload: { type: 'error'; err: { message: string; stack?: string } }): void;\n (event: string, payload?: any): void;\n };\n};\n\n/**\n * Vite ResolvedConfig 类型(精简版)\n */\ntype ResolvedConfigLike = {\n command: 'serve' | 'build' | string;\n version?: string;\n plugins?: any[];\n build?: {\n outDir?: string;\n };\n root?: string;\n};\n\n/**\n * 发送错误覆盖层到客户端(优先定向发送,避免首屏时广播命中不到当前 client)\n */\nfunction sendErrorOverlay(args: { server: DevServerLike; message: string; lang: Lang; client?: DevClientLike; needMergeMessage: boolean }) {\n const { server, message, lang, client, needMergeMessage } = args;\n\n const fullMessage = needMergeMessage ? `${getMessageHeader(lang)}\\n${message}` : getMessageHeader(lang);\n\n const payload = {\n type: 'error',\n err: {\n message: fullMessage,\n stack: message,\n },\n } as const;\n\n if (client?.send) {\n client.send(payload);\n return;\n }\n\n server.ws.send(payload);\n}\n\n/**\n * 客户端上报的消息载荷\n */\ntype ClientReportPayload = {\n message: string;\n /** 用于 ACK 去重/确认(客户端可不传,服务端会回退使用 message 截断值) */\n key?: string;\n /** 客户端运行时语言(推荐从 main.ts 传入并上报),用于决定 overlay header 语言 */\n lang?: Lang;\n};\n\n/**\n * Vite 插件:Vue Root Validator\n *\n * 用于检测 Vue 组件在 <Transition> 内渲染时的多根节点问题\n *\n * @returns Vite 插件对象\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n *\n * export default defineConfig({\n * plugins: [\n * vitePluginVueTransitionRootValidator()\n * ]\n * });\n * ```\n */\nexport default function vitePluginVueTransitionRootValidator() {\n let resolved: ResolvedConfigLike;\n let needMergeMessage: boolean;\n\n return {\n name: 'vite-plugin-vue-transition-root-validator',\n\n /**\n * 保存解析后的配置\n */\n configResolved(config: ResolvedConfigLike) {\n resolved = config;\n // 判断 Vite 版本:7 以下需要把 stack 合入 message\n const viteVersion = config.version;\n const viteMajorVersion = viteVersion ? parseInt(viteVersion.split('.')[0], 10) : 6;\n needMergeMessage = isNaN(viteMajorVersion) || viteMajorVersion < 7;\n },\n\n /**\n * 配置开发服务器\n * 监听客户端上报的警告消息,并通过 error overlay 显示\n */\n configureServer(server: DevServerLike) {\n if (resolved.command !== 'serve') return;\n\n // 用于去重,避免同一客户端重复发送相同消息\n const lastByClient = new WeakMap<object, string>();\n\n // 监听客户端上报的警告\n server.ws.on('vite-plugin-vue-transition-root-validator:vue-warn', (payload: ClientReportPayload, client: object) => {\n if (!payload?.message) return;\n\n // 去重处理\n const key = payload.key ?? payload.message.slice(0, 800);\n const prev = lastByClient.get(client as unknown as object);\n if (prev === key) {\n // 仍然回 ACK,避免客户端重试积压\n (client as any as DevClientLike)?.send?.('vite-plugin-vue-transition-root-validator:ack', { key });\n return;\n }\n lastByClient.set(client as unknown as object, key);\n\n const effectiveLang: Lang = payload.lang ?? 'en';\n\n // 发送错误覆盖层\n sendErrorOverlay({\n server,\n message: payload.message,\n lang: effectiveLang,\n client: client as any as DevClientLike,\n needMergeMessage\n });\n\n // 回 ACK,通知客户端该消息已被处理(用于清理重试队列)\n (client as any as DevClientLike)?.send?.('vite-plugin-vue-transition-root-validator:ack', { key });\n });\n },\n\n /**\n * 解析虚拟模块\n * 处理 'virtual:vue-transition-root-validator' 模块的导入\n */\n resolveId(id: string) {\n if (id === 'virtual:vue-transition-root-validator') {\n // 返回一个虚拟模块 ID,加上 \\0 前缀表示这是一个虚拟模块\n return '\\0virtual:vue-transition-root-validator';\n }\n return null;\n },\n\n /**\n * 加载虚拟模块\n * 返回虚拟模块的代码内容\n */\n load(id: string) {\n if (id === '\\0virtual:vue-transition-root-validator') {\n const clientEntryTs = fileURLToPath(new URL('./client.ts', import.meta.url));\n const clientEntryJs = fileURLToPath(new URL('./client.js', import.meta.url));\n const clientEntry = existsSync(clientEntryTs) ? clientEntryTs : clientEntryJs;\n const clientUrl = `/@fs/${clientEntry.replace(/\\\\/g, '/')}`;\n\n // 返回虚拟模块代码:重新导出 client.ts 的函数\n return `\n// 虚拟模块:vue-transition-root-validator\n// 此模块由 vite-plugin-vue-transition-root-validator 插件自动生成\n\nimport { setupVueRootValidator } from ${JSON.stringify(clientUrl)};\n\n// 重新导出函数\nexport { setupVueRootValidator };\n`;\n }\n return null;\n },\n\n closeBundle(options: any) {\n console.log('进入closeBundle', options);\n try {\n // 1. 获取 Vite 打包的输出目录(默认 dist,支持用户自定义配置)\n const outDir = options.config.build.outDir;\n // 拼接 HTML 文件的完整路径(默认打包生成 index.html,支持自定义 HTML 文件名)\n const htmlFilePath = path.resolve(process.cwd(), outDir, 'index.html');\n\n // 2. 先判断 HTML 文件是否存在(避免文件不存在导致写入报错)\n if (!fs.existsSync(htmlFilePath)) {\n console.log(`[空HTML插件] 未找到 HTML 文件:${htmlFilePath}`);\n return;\n }\n\n // 3. 执行你的「自定义判断逻辑」(这里是示例,你可替换为自己的业务判断)\n // 示例:比如判断打包环境是否为生产环境,或是否满足某个自定义条件\n const plugins = resolved.plugins || [];\n console.log('plugins', plugins);\n const hasSvgBuilder = plugins.some((p: any) => p.name === 'svgBuilder');\n\n\n\n if (!hasSvgBuilder) {\n const outDir = resolved.build?.outDir ?? 'dist';\n const root = resolved.root ?? process.cwd();\n const distDir = resolve(root, outDir);\n const indexHtmlPath = resolve(distDir, 'index.html');\n\n\n\n // 4. 满足条件,将 HTML 文件内容置空(写入空字符串)\n fs.writeFileSync(htmlFilePath, '', 'utf-8');\n console.log(`[空HTML插件] 已成功将 HTML 文件置空:${htmlFilePath}`);\n return;\n }\n\n console.log(`[空HTML插件] 不满足置空条件,跳过 HTML 置空`);\n\n } catch (error: any) {\n // 捕获异常,避免插件报错导致整个打包流程异常终止\n console.error(`[空HTML插件] 操作失败:`, error.message);\n }\n\n }\n };\n}\n\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,MAAM,eAAe;CACnB,IAAI;EACF,eAAe;EACf,mBAAmB;;;;;;;;;;;;;;;;;EAiBpB;CACD,IAAI;EACF,eAAe;EACf,mBAAmB;;;;;;;;;;;;;;;;;EAiBpB;CACF;AAiED,SAAgB,iBAAiB,MAAoB;AACnD,QAAO,aAAa,MAAM;;;;;;;;ACtE5B,SAAS,iBAAiB,MAAiH;CACzI,MAAM,EAAE,QAAQ,SAAS,MAAM,QAAQ,qBAAqB;CAI5D,MAAM,UAAU;EACd,MAAM;EACN,KAAK;GACH,SALgB,mBAAmB,GAAG,iBAAiB,KAAK,CAAC,IAAI,YAAY,iBAAiB,KAAK;GAMnG,OAAO;GACR;EACF;AAED,KAAI,QAAQ,MAAM;AAChB,SAAO,KAAK,QAAQ;AACpB;;AAGF,QAAO,GAAG,KAAK,QAAQ;;;;;;;;;;;;;;;;;;;;;AAiCzB,SAAwB,uCAAuC;CAC7D,IAAI;CACJ,IAAI;AAEJ,QAAO;EACL,MAAM;EAKN,eAAe,QAA4B;AACzC,cAAW;GAEX,MAAM,cAAc,OAAO;GAC3B,MAAM,mBAAmB,cAAc,SAAS,YAAY,MAAM,IAAI,CAAC,IAAI,GAAG,GAAG;AACjF,sBAAmB,MAAM,iBAAiB,IAAI,mBAAmB;;EAOnE,gBAAgB,QAAuB;AACrC,OAAI,SAAS,YAAY,QAAS;GAGlC,MAAM,+BAAe,IAAI,SAAyB;AAGlD,UAAO,GAAG,GAAG,uDAAuD,SAA8B,WAAmB;AACnH,QAAI,CAAC,SAAS,QAAS;IAGvB,MAAM,MAAM,QAAQ,OAAO,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAExD,QADa,aAAa,IAAI,OAA4B,KAC7C,KAAK;AAEhB,KAAC,QAAiC,OAAO,iDAAiD,EAAE,KAAK,CAAC;AAClG;;AAEF,iBAAa,IAAI,QAA6B,IAAI;IAElD,MAAM,gBAAsB,QAAQ,QAAQ;AAG5C,qBAAiB;KACf;KACA,SAAS,QAAQ;KACjB,MAAM;KACE;KACR;KACD,CAAC;AAGF,IAAC,QAAiC,OAAO,iDAAiD,EAAE,KAAK,CAAC;KAClG;;EAOJ,UAAU,IAAY;AACpB,OAAI,OAAO,wCAET,QAAO;AAET,UAAO;;EAOT,KAAK,IAAY;AACf,OAAI,OAAO,2CAA2C;IACpD,MAAM,4CAA8B,IAAI,IAAI,6DAA+B,CAAC;IAC5E,MAAM,4CAA8B,IAAI,IAAI,6DAA+B,CAAC;IAE5E,MAAM,YAAY,iCADa,cAAc,GAAG,gBAAgB,eAC1B,QAAQ,OAAO,IAAI;AAGzD,WAAO;;;;wCAIyB,KAAK,UAAU,UAAU,CAAC;;;;;;AAM5D,UAAO;;EAGT,YAAY,SAAc;AACxB,WAAQ,IAAI,iBAAiB,QAAQ;AACrC,OAAI;IAEF,MAAM,SAAS,QAAQ,OAAO,MAAM;IAEpC,MAAM,eAAe,aAAK,QAAQ,QAAQ,KAAK,EAAE,QAAQ,aAAa;AAGtE,QAAI,CAACA,gBAAG,WAAW,aAAa,EAAE;AAChC,aAAQ,IAAI,yBAAyB,eAAe;AACpD;;IAKF,MAAM,UAAU,SAAS,WAAW,EAAE;AACtC,YAAQ,IAAI,WAAW,QAAQ;AAK/B,QAAI,CAJkB,QAAQ,MAAM,MAAW,EAAE,SAAS,aAAa,EAInD;KAClB,MAAMC,WAAS,SAAS,OAAO,UAAU;AAGnB,mDAFT,SAAS,QAAQ,QAAQ,KAAK,EACbA,SAAO,EACE,aAAa;AAKpD,qBAAG,cAAc,cAAc,IAAI,QAAQ;AAC3C,aAAQ,IAAI,4BAA4B,eAAe;AACvD;;AAGF,YAAQ,IAAI,+BAA+B;YAEpC,OAAY;AAEnB,YAAQ,MAAM,mBAAmB,MAAM,QAAQ;;;EAIpD"}
package/dist/index.d.cts CHANGED
@@ -20,6 +20,18 @@ type DevServerLike = {
20
20
  };
21
21
  };
22
22
  };
23
+ /**
24
+ * Vite ResolvedConfig 类型(精简版)
25
+ */
26
+ type ResolvedConfigLike = {
27
+ command: 'serve' | 'build' | string;
28
+ version?: string;
29
+ plugins?: any[];
30
+ build?: {
31
+ outDir?: string;
32
+ };
33
+ root?: string;
34
+ };
23
35
  /**
24
36
  * Vite 插件:Vue Root Validator
25
37
  *
@@ -44,7 +56,7 @@ declare function vitePluginVueTransitionRootValidator(): {
44
56
  /**
45
57
  * 保存解析后的配置
46
58
  */
47
- configResolved(config: any): void;
59
+ configResolved(config: ResolvedConfigLike): void;
48
60
  /**
49
61
  * 配置开发服务器
50
62
  * 监听客户端上报的警告消息,并通过 error overlay 显示
@@ -60,7 +72,7 @@ declare function vitePluginVueTransitionRootValidator(): {
60
72
  * 返回虚拟模块的代码内容
61
73
  */
62
74
  load(id: string): string | null;
63
- buildEnd(err?: Error): void;
75
+ closeBundle(options: any): void;
64
76
  };
65
77
  export = vitePluginVueTransitionRootValidator;
66
- //# sourceMappingURL=index-BFTbLKhl.d.cts.map
78
+ //# sourceMappingURL=index-DqgTaEhZ.d.cts.map
package/dist/index.d.ts CHANGED
@@ -20,6 +20,18 @@ type DevServerLike = {
20
20
  };
21
21
  };
22
22
  };
23
+ /**
24
+ * Vite ResolvedConfig 类型(精简版)
25
+ */
26
+ type ResolvedConfigLike = {
27
+ command: 'serve' | 'build' | string;
28
+ version?: string;
29
+ plugins?: any[];
30
+ build?: {
31
+ outDir?: string;
32
+ };
33
+ root?: string;
34
+ };
23
35
  /**
24
36
  * Vite 插件:Vue Root Validator
25
37
  *
@@ -44,7 +56,7 @@ declare function vitePluginVueTransitionRootValidator(): {
44
56
  /**
45
57
  * 保存解析后的配置
46
58
  */
47
- configResolved(config: any): void;
59
+ configResolved(config: ResolvedConfigLike): void;
48
60
  /**
49
61
  * 配置开发服务器
50
62
  * 监听客户端上报的警告消息,并通过 error overlay 显示
@@ -60,8 +72,8 @@ declare function vitePluginVueTransitionRootValidator(): {
60
72
  * 返回虚拟模块的代码内容
61
73
  */
62
74
  load(id: string): string | null;
63
- buildEnd(err?: Error): void;
75
+ closeBundle(options: any): void;
64
76
  };
65
77
  //#endregion
66
78
  export { vitePluginVueTransitionRootValidator as default };
67
- //# sourceMappingURL=index-DIr66WSZ.d.ts.map
79
+ //# sourceMappingURL=index-DyJ9Q1c6.d.ts.map
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { fileURLToPath } from "node:url";
2
- import { existsSync, writeFileSync } from "node:fs";
2
+ import fs, { existsSync } from "node:fs";
3
+ import path from "path";
3
4
  import { resolve } from "node:path";
4
5
 
5
6
  //#region src/i18n.ts
@@ -55,11 +56,11 @@ function getMessageHeader(lang) {
55
56
  * 发送错误覆盖层到客户端(优先定向发送,避免首屏时广播命中不到当前 client)
56
57
  */
57
58
  function sendErrorOverlay(args) {
58
- const { server, message, lang, client } = args;
59
+ const { server, message, lang, client, needMergeMessage } = args;
59
60
  const payload = {
60
61
  type: "error",
61
62
  err: {
62
- message: getMessageHeader(lang),
63
+ message: needMergeMessage ? `${getMessageHeader(lang)}\n${message}` : getMessageHeader(lang),
63
64
  stack: message
64
65
  }
65
66
  };
@@ -90,10 +91,14 @@ function sendErrorOverlay(args) {
90
91
  */
91
92
  function vitePluginVueTransitionRootValidator() {
92
93
  let resolved;
94
+ let needMergeMessage;
93
95
  return {
94
96
  name: "vite-plugin-vue-transition-root-validator",
95
97
  configResolved(config) {
96
98
  resolved = config;
99
+ const viteVersion = config.version;
100
+ const viteMajorVersion = viteVersion ? parseInt(viteVersion.split(".")[0], 10) : 6;
101
+ needMergeMessage = isNaN(viteMajorVersion) || viteMajorVersion < 7;
97
102
  },
98
103
  configureServer(server) {
99
104
  if (resolved.command !== "serve") return;
@@ -111,7 +116,8 @@ function vitePluginVueTransitionRootValidator() {
111
116
  server,
112
117
  message: payload.message,
113
118
  lang: effectiveLang,
114
- client
119
+ client,
120
+ needMergeMessage
115
121
  });
116
122
  client?.send?.("vite-plugin-vue-transition-root-validator:ack", { key });
117
123
  });
@@ -137,12 +143,27 @@ export { setupVueRootValidator };
137
143
  }
138
144
  return null;
139
145
  },
140
- buildEnd(err) {
141
- if (err) return;
142
- if (!(resolved.plugins || []).some((p) => p.name === "svgBuilder")) {
143
- const outDir = resolved.build?.outDir ?? "dist";
144
- const indexHtmlPath = resolve(resolve(resolved.root ?? process.cwd(), outDir), "index.html");
145
- if (existsSync(indexHtmlPath)) writeFileSync(indexHtmlPath, "");
146
+ closeBundle(options) {
147
+ console.log("进入closeBundle", options);
148
+ try {
149
+ const outDir = options.config.build.outDir;
150
+ const htmlFilePath = path.resolve(process.cwd(), outDir, "index.html");
151
+ if (!fs.existsSync(htmlFilePath)) {
152
+ console.log(`[空HTML插件] 未找到 HTML 文件:${htmlFilePath}`);
153
+ return;
154
+ }
155
+ const plugins = resolved.plugins || [];
156
+ console.log("plugins", plugins);
157
+ if (!plugins.some((p) => p.name === "svgBuilder")) {
158
+ const outDir$1 = resolved.build?.outDir ?? "dist";
159
+ resolve(resolve(resolved.root ?? process.cwd(), outDir$1), "index.html");
160
+ fs.writeFileSync(htmlFilePath, "", "utf-8");
161
+ console.log(`[空HTML插件] 已成功将 HTML 文件置空:${htmlFilePath}`);
162
+ return;
163
+ }
164
+ console.log(`[空HTML插件] 不满足置空条件,跳过 HTML 置空`);
165
+ } catch (error) {
166
+ console.error(`[空HTML插件] 操作失败:`, error.message);
146
167
  }
147
168
  }
148
169
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/i18n.ts","../src/index.ts"],"sourcesContent":["import type { Lang } from './types.ts';\n\nexport type TransitionRootMessageContext = {\n file?: string;\n url?: string;\n routeKey?: string;\n component?: string;\n};\n\nconst translations = {\n zh: {\n messageHeader: '[vite-plugin-vue-transition-root-validator] 检测到 Vue Transition 多根节点错误',\n setupInstructions: `\n如何在项目中启用此插件:\n\n1. 在 vite.config.ts 中添加插件:\n import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n\n plugins: [\n vitePluginVueTransitionRootValidator()\n ]\n\n2. 在 src/main.ts 中初始化:\n import { setupVueRootValidator } from 'virtual:vue-transition-root-validator';\n\n const app = createApp(App);\n setupVueRootValidator(app, { lang: 'zh' });\n app.mount('#app');\n`\n },\n en: {\n messageHeader: '[vite-plugin-vue-transition-root-validator] Vue Transition Multiple Root Nodes Error',\n setupInstructions: `\nHow to enable this plugin in your project:\n\n1. Add plugin in vite.config.ts:\n import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n\n plugins: [\n vitePluginVueTransitionRootValidator()\n ]\n\n2. Initialize in src/main.ts:\n import { setupVueRootValidator } from 'virtual:vue-transition-root-validator';\n\n const app = createApp(App);\n setupVueRootValidator(app, { lang: 'en' });\n app.mount('#app');\n`\n }\n};\n\nexport function formatTransitionRootMessage(lang: Lang, ctx: TransitionRootMessageContext): string {\n if (lang === 'zh') {\n const title = 'Vue <Transition> 要求插槽内容具有单一的“元素根节点”。';\n const lines: string[] = [];\n lines.push(title);\n\n if (ctx.file) lines.push(`\\n文件: ${ctx.file}`);\n if (ctx.url) lines.push(`URL: ${ctx.url}`);\n\n const meta: string[] = [];\n if (ctx.component) meta.push(`component=${ctx.component}`);\n if (ctx.routeKey) meta.push(`key=${ctx.routeKey}`);\n if (meta.length) lines.push(`上下文: ${meta.join(' ')}`);\n\n lines.push(\n '\\n如何修复:\\n' +\n `- 在${ctx.file ? `文件 ${ctx.file}` : '该组件'}的 <template> 最外层添加一个容器标签(如 <div> / <main>),把所有内容包起来,确保最终只渲染出一个根“标签元素”。\\n` +\n '- 根节点不能是多个并列元素(Fragment/多根),也不能是纯文本或注释。\\n' +\n '- 如果根部使用了 v-if / v-else,确保每个分支都只渲染一个根标签元素。'\n );\n\n lines.push(\n '\\n为什么会这样:\\n' +\n 'Vue 的 <Transition> 需要把过渡 class 应用在一个真实的 DOM 元素上;' +\n '当插槽内容渲染出的根节点不是“单一元素”(例如 Fragment、多根、纯文本或注释)时,就无法执行进入/离开过渡。'\n );\n\n lines.push('\\n相关文档:\\nhttps://cn.vuejs.org/guide/built-ins/transition#the-transition-component');\n\n return lines.join('\\n');\n }\n\n // English\n const title = 'Vue <Transition> requires a single element root node in its slot.';\n const lines: string[] = [];\n lines.push(title);\n\n if (ctx.file) lines.push(`\\nFile: ${ctx.file}`);\n if (ctx.url) lines.push(`URL: ${ctx.url}`);\n\n const meta: string[] = [];\n if (ctx.component) meta.push(`component=${ctx.component}`);\n if (ctx.routeKey) meta.push(`key=${ctx.routeKey}`);\n if (meta.length) lines.push(`Context: ${meta.join(' ')}`);\n\n lines.push(\n '\\nHow to fix:\\n' +\n `- In the <template> of ${ctx.file ? `file ${ctx.file}` : 'this component'}, wrap everything with a single container element (e.g. <div> / <main>), so the final render has exactly one root *element*.\\n` +\n '- The root cannot be a Fragment (multiple siblings), plain text, or a comment.\\n' +\n '- If you use v-if / v-else at the root, ensure each branch renders exactly one root element.'\n );\n\n lines.push(\n '\\nWhy this happens:\\n' +\n 'Vue <Transition> needs to apply transition classes to a real DOM element. ' +\n 'If the slot content renders a non-element root (Fragment/multiple roots/text/comment), Vue cannot animate it.'\n );\n\n lines.push('\\nDocs:\\nhttps://cn.vuejs.org/guide/built-ins/transition#the-transition-component');\n\n return lines.join('\\n');\n}\n\nexport function getMessageHeader(lang: Lang): string {\n return translations[lang].messageHeader;\n}\n\nexport function getSetupInstructions(lang: Lang): string {\n return translations[lang].setupInstructions;\n}\n","import { fileURLToPath } from 'node:url';\nimport { existsSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { Lang } from './types.ts';\nimport { getMessageHeader } from './i18n.ts';\n\n/**\n * Vite DevServer 类型(精简版)\n */\ntype DevServerLike = {\n ws: {\n send: (payload: { type: 'error'; err: { message: string; stack?: string } }) => void;\n on: (event: string, listener: (payload: any, client: any) => void) => void;\n };\n config: {\n logger: {\n warn: (msg: string) => void;\n info: (msg: string) => void;\n };\n };\n};\n\ntype DevClientLike = {\n send?: {\n (payload: { type: 'error'; err: { message: string; stack?: string } }): void;\n (event: string, payload?: any): void;\n };\n};\n\n/**\n * Vite ResolvedConfig 类型(精简版)\n */\ntype ResolvedConfigLike = {\n command: 'serve' | 'build' | string;\n};\n\n/**\n * 发送错误覆盖层到客户端(优先定向发送,避免首屏时广播命中不到当前 client)\n */\nfunction sendErrorOverlay(args: { server: DevServerLike; message: string; lang: Lang; client?: DevClientLike }) {\n const { server, message, lang, client } = args;\n const payload = {\n type: 'error',\n err: {\n message: getMessageHeader(lang),\n stack: message\n }\n } as const;\n\n if (client?.send) {\n client.send(payload);\n return;\n }\n\n server.ws.send(payload);\n}\n\n/**\n * 客户端上报的消息载荷\n */\ntype ClientReportPayload = {\n message: string;\n /** 用于 ACK 去重/确认(客户端可不传,服务端会回退使用 message 截断值) */\n key?: string;\n /** 客户端运行时语言(推荐从 main.ts 传入并上报),用于决定 overlay header 语言 */\n lang?: Lang;\n};\n\n/**\n * Vite 插件:Vue Root Validator\n *\n * 用于检测 Vue 组件在 <Transition> 内渲染时的多根节点问题\n *\n * @returns Vite 插件对象\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n *\n * export default defineConfig({\n * plugins: [\n * vitePluginVueTransitionRootValidator()\n * ]\n * });\n * ```\n */\nexport default function vitePluginVueTransitionRootValidator() {\n let resolved: ResolvedConfigLike & { plugins?: any[]; root?: string; build?: { outDir?: string } };\n\n return {\n name: 'vite-plugin-vue-transition-root-validator',\n\n /**\n * 保存解析后的配置\n */\n configResolved(config: any) {\n resolved = config;\n },\n\n /**\n * 配置开发服务器\n * 监听客户端上报的警告消息,并通过 error overlay 显示\n */\n configureServer(server: DevServerLike) {\n if (resolved.command !== 'serve') return;\n\n // 用于去重,避免同一客户端重复发送相同消息\n const lastByClient = new WeakMap<object, string>();\n\n // 监听客户端上报的警告\n server.ws.on('vite-plugin-vue-transition-root-validator:vue-warn', (payload: ClientReportPayload, client: object) => {\n if (!payload?.message) return;\n\n // 去重处理\n const key = payload.key ?? payload.message.slice(0, 800);\n const prev = lastByClient.get(client as unknown as object);\n if (prev === key) {\n // 仍然回 ACK,避免客户端重试积压\n (client as any as DevClientLike)?.send?.('vite-plugin-vue-transition-root-validator:ack', { key });\n return;\n }\n lastByClient.set(client as unknown as object, key);\n\n const effectiveLang: Lang = payload.lang ?? 'en';\n\n // 发送错误覆盖层\n sendErrorOverlay({\n server,\n message: payload.message,\n lang: effectiveLang,\n client: client as any as DevClientLike\n });\n\n // 回 ACK,通知客户端该消息已被处理(用于清理重试队列)\n (client as any as DevClientLike)?.send?.('vite-plugin-vue-transition-root-validator:ack', { key });\n });\n },\n\n /**\n * 解析虚拟模块\n * 处理 'virtual:vue-transition-root-validator' 模块的导入\n */\n resolveId(id: string) {\n if (id === 'virtual:vue-transition-root-validator') {\n // 返回一个虚拟模块 ID,加上 \\0 前缀表示这是一个虚拟模块\n return '\\0virtual:vue-transition-root-validator';\n }\n return null;\n },\n\n /**\n * 加载虚拟模块\n * 返回虚拟模块的代码内容\n */\n load(id: string) {\n if (id === '\\0virtual:vue-transition-root-validator') {\n const clientEntryTs = fileURLToPath(new URL('./client.ts', import.meta.url));\n const clientEntryJs = fileURLToPath(new URL('./client.js', import.meta.url));\n const clientEntry = existsSync(clientEntryTs) ? clientEntryTs : clientEntryJs;\n const clientUrl = `/@fs/${clientEntry.replace(/\\\\/g, '/')}`;\n\n // 返回虚拟模块代码:重新导出 client.ts 的函数\n return `\n// 虚拟模块:vue-transition-root-validator\n// 此模块由 vite-plugin-vue-transition-root-validator 插件自动生成\n\nimport { setupVueRootValidator } from ${JSON.stringify(clientUrl)};\n\n// 重新导出函数\nexport { setupVueRootValidator };\n`;\n }\n return null;\n },\n\n buildEnd(err?: Error) {\n if (err) return;\n\n const plugins = resolved.plugins || [];\n const hasSvgBuilder = plugins.some((p: any) => p.name === 'svgBuilder');\n\n if (!hasSvgBuilder) {\n const outDir = resolved.build?.outDir ?? 'dist';\n const root = resolved.root ?? process.cwd();\n const distDir = resolve(root, outDir);\n const indexHtmlPath = resolve(distDir, 'index.html');\n\n if (existsSync(indexHtmlPath)) {\n writeFileSync(indexHtmlPath, '');\n }\n }\n }\n };\n}\n\n\n"],"mappings":";;;;;AASA,MAAM,eAAe;CACnB,IAAI;EACF,eAAe;EACf,mBAAmB;;;;;;;;;;;;;;;;;EAiBpB;CACD,IAAI;EACF,eAAe;EACf,mBAAmB;;;;;;;;;;;;;;;;;EAiBpB;CACF;AAiED,SAAgB,iBAAiB,MAAoB;AACnD,QAAO,aAAa,MAAM;;;;;;;;AC7E5B,SAAS,iBAAiB,MAAsF;CAC9G,MAAM,EAAE,QAAQ,SAAS,MAAM,WAAW;CAC1C,MAAM,UAAU;EACd,MAAM;EACN,KAAK;GACH,SAAS,iBAAiB,KAAK;GAC/B,OAAO;GACR;EACF;AAED,KAAI,QAAQ,MAAM;AAChB,SAAO,KAAK,QAAQ;AACpB;;AAGF,QAAO,GAAG,KAAK,QAAQ;;;;;;;;;;;;;;;;;;;;;AAiCzB,SAAwB,uCAAuC;CAC7D,IAAI;AAEJ,QAAO;EACL,MAAM;EAKN,eAAe,QAAa;AAC1B,cAAW;;EAOb,gBAAgB,QAAuB;AACrC,OAAI,SAAS,YAAY,QAAS;GAGlC,MAAM,+BAAe,IAAI,SAAyB;AAGlD,UAAO,GAAG,GAAG,uDAAuD,SAA8B,WAAmB;AACnH,QAAI,CAAC,SAAS,QAAS;IAGvB,MAAM,MAAM,QAAQ,OAAO,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAExD,QADa,aAAa,IAAI,OAA4B,KAC7C,KAAK;AAEhB,KAAC,QAAiC,OAAO,iDAAiD,EAAE,KAAK,CAAC;AAClG;;AAEF,iBAAa,IAAI,QAA6B,IAAI;IAElD,MAAM,gBAAsB,QAAQ,QAAQ;AAG5C,qBAAiB;KACf;KACA,SAAS,QAAQ;KACjB,MAAM;KACE;KACT,CAAC;AAGF,IAAC,QAAiC,OAAO,iDAAiD,EAAE,KAAK,CAAC;KAClG;;EAOJ,UAAU,IAAY;AACpB,OAAI,OAAO,wCAET,QAAO;AAET,UAAO;;EAOT,KAAK,IAAY;AACf,OAAI,OAAO,2CAA2C;IACpD,MAAM,gBAAgB,cAAc,IAAI,IAAI,eAAe,OAAO,KAAK,IAAI,CAAC;IAC5E,MAAM,gBAAgB,cAAc,IAAI,IAAI,eAAe,OAAO,KAAK,IAAI,CAAC;IAE5E,MAAM,YAAY,SADE,WAAW,cAAc,GAAG,gBAAgB,eAC1B,QAAQ,OAAO,IAAI;AAGzD,WAAO;;;;wCAIyB,KAAK,UAAU,UAAU,CAAC;;;;;;AAM5D,UAAO;;EAGT,SAAS,KAAa;AACpB,OAAI,IAAK;AAKT,OAAI,EAHY,SAAS,WAAW,EAAE,EACR,MAAM,MAAW,EAAE,SAAS,aAAa,EAEnD;IAClB,MAAM,SAAS,SAAS,OAAO,UAAU;IAGzC,MAAM,gBAAgB,QADN,QADH,SAAS,QAAQ,QAAQ,KAAK,EACb,OAAO,EACE,aAAa;AAEpD,QAAI,WAAW,cAAc,CAC3B,eAAc,eAAe,GAAG;;;EAIvC"}
1
+ {"version":3,"file":"index.js","names":["outDir"],"sources":["../src/i18n.ts","../src/index.ts"],"sourcesContent":["import type { Lang } from './types.ts';\n\nexport type TransitionRootMessageContext = {\n file?: string;\n url?: string;\n routeKey?: string;\n component?: string;\n};\n\nconst translations = {\n zh: {\n messageHeader: '[vite-plugin-vue-transition-root-validator] 检测到 Vue Transition 多根节点错误',\n setupInstructions: `\n如何在项目中启用此插件:\n\n1. 在 vite.config.ts 中添加插件:\n import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n\n plugins: [\n vitePluginVueTransitionRootValidator()\n ]\n\n2. 在 src/main.ts 中初始化:\n import { setupVueRootValidator } from 'virtual:vue-transition-root-validator';\n\n const app = createApp(App);\n setupVueRootValidator(app, { lang: 'zh' });\n app.mount('#app');\n`\n },\n en: {\n messageHeader: '[vite-plugin-vue-transition-root-validator] Vue Transition Multiple Root Nodes Error',\n setupInstructions: `\nHow to enable this plugin in your project:\n\n1. Add plugin in vite.config.ts:\n import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n\n plugins: [\n vitePluginVueTransitionRootValidator()\n ]\n\n2. Initialize in src/main.ts:\n import { setupVueRootValidator } from 'virtual:vue-transition-root-validator';\n\n const app = createApp(App);\n setupVueRootValidator(app, { lang: 'en' });\n app.mount('#app');\n`\n }\n};\n\nexport function formatTransitionRootMessage(lang: Lang, ctx: TransitionRootMessageContext): string {\n if (lang === 'zh') {\n const title = 'Vue <Transition> 要求插槽内容具有单一的“元素根节点”。';\n const lines: string[] = [];\n lines.push(title);\n\n if (ctx.file) lines.push(`\\n文件: ${ctx.file}`);\n if (ctx.url) lines.push(`URL: ${ctx.url}`);\n\n const meta: string[] = [];\n if (ctx.component) meta.push(`component=${ctx.component}`);\n if (ctx.routeKey) meta.push(`key=${ctx.routeKey}`);\n if (meta.length) lines.push(`上下文: ${meta.join(' ')}`);\n\n lines.push(\n '\\n如何修复:\\n' +\n `- 在${ctx.file ? `文件 ${ctx.file}` : '该组件'}的 <template> 最外层添加一个容器标签(如 <div> / <main>),把所有内容包起来,确保最终只渲染出一个根“标签元素”。\\n` +\n '- 根节点不能是多个并列元素(Fragment/多根),也不能是纯文本或注释。\\n' +\n '- 如果根部使用了 v-if / v-else,确保每个分支都只渲染一个根标签元素。'\n );\n\n lines.push(\n '\\n为什么会这样:\\n' +\n 'Vue 的 <Transition> 需要把过渡 class 应用在一个真实的 DOM 元素上;' +\n '当插槽内容渲染出的根节点不是“单一元素”(例如 Fragment、多根、纯文本或注释)时,就无法执行进入/离开过渡。'\n );\n\n lines.push('\\n相关文档:\\nhttps://cn.vuejs.org/guide/built-ins/transition#the-transition-component');\n\n return lines.join('\\n');\n }\n\n // English\n const title = 'Vue <Transition> requires a single element root node in its slot.';\n const lines: string[] = [];\n lines.push(title);\n\n if (ctx.file) lines.push(`\\nFile: ${ctx.file}`);\n if (ctx.url) lines.push(`URL: ${ctx.url}`);\n\n const meta: string[] = [];\n if (ctx.component) meta.push(`component=${ctx.component}`);\n if (ctx.routeKey) meta.push(`key=${ctx.routeKey}`);\n if (meta.length) lines.push(`Context: ${meta.join(' ')}`);\n\n lines.push(\n '\\nHow to fix:\\n' +\n `- In the <template> of ${ctx.file ? `file ${ctx.file}` : 'this component'}, wrap everything with a single container element (e.g. <div> / <main>), so the final render has exactly one root *element*.\\n` +\n '- The root cannot be a Fragment (multiple siblings), plain text, or a comment.\\n' +\n '- If you use v-if / v-else at the root, ensure each branch renders exactly one root element.'\n );\n\n lines.push(\n '\\nWhy this happens:\\n' +\n 'Vue <Transition> needs to apply transition classes to a real DOM element. ' +\n 'If the slot content renders a non-element root (Fragment/multiple roots/text/comment), Vue cannot animate it.'\n );\n\n lines.push('\\nDocs:\\nhttps://cn.vuejs.org/guide/built-ins/transition#the-transition-component');\n\n return lines.join('\\n');\n}\n\nexport function getMessageHeader(lang: Lang): string {\n return translations[lang].messageHeader;\n}\n\nexport function getSetupInstructions(lang: Lang): string {\n return translations[lang].setupInstructions;\n}\n","import { fileURLToPath } from 'node:url';\nimport fs, { existsSync } from 'node:fs';\nimport path from 'path';\nimport { resolve } from 'node:path';\nimport type { Lang } from './types.ts';\nimport { getMessageHeader } from './i18n.ts';\n\n/**\n * Vite DevServer 类型(精简版)\n */\ntype DevServerLike = {\n ws: {\n send: (payload: { type: 'error'; err: { message: string; stack?: string } }) => void;\n on: (event: string, listener: (payload: any, client: any) => void) => void;\n };\n config: {\n logger: {\n warn: (msg: string) => void;\n info: (msg: string) => void;\n };\n };\n};\n\ntype DevClientLike = {\n send?: {\n (payload: { type: 'error'; err: { message: string; stack?: string } }): void;\n (event: string, payload?: any): void;\n };\n};\n\n/**\n * Vite ResolvedConfig 类型(精简版)\n */\ntype ResolvedConfigLike = {\n command: 'serve' | 'build' | string;\n version?: string;\n plugins?: any[];\n build?: {\n outDir?: string;\n };\n root?: string;\n};\n\n/**\n * 发送错误覆盖层到客户端(优先定向发送,避免首屏时广播命中不到当前 client)\n */\nfunction sendErrorOverlay(args: { server: DevServerLike; message: string; lang: Lang; client?: DevClientLike; needMergeMessage: boolean }) {\n const { server, message, lang, client, needMergeMessage } = args;\n\n const fullMessage = needMergeMessage ? `${getMessageHeader(lang)}\\n${message}` : getMessageHeader(lang);\n\n const payload = {\n type: 'error',\n err: {\n message: fullMessage,\n stack: message,\n },\n } as const;\n\n if (client?.send) {\n client.send(payload);\n return;\n }\n\n server.ws.send(payload);\n}\n\n/**\n * 客户端上报的消息载荷\n */\ntype ClientReportPayload = {\n message: string;\n /** 用于 ACK 去重/确认(客户端可不传,服务端会回退使用 message 截断值) */\n key?: string;\n /** 客户端运行时语言(推荐从 main.ts 传入并上报),用于决定 overlay header 语言 */\n lang?: Lang;\n};\n\n/**\n * Vite 插件:Vue Root Validator\n *\n * 用于检测 Vue 组件在 <Transition> 内渲染时的多根节点问题\n *\n * @returns Vite 插件对象\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import vitePluginVueTransitionRootValidator from 'vite-plugin-vue-transition-root-validator';\n *\n * export default defineConfig({\n * plugins: [\n * vitePluginVueTransitionRootValidator()\n * ]\n * });\n * ```\n */\nexport default function vitePluginVueTransitionRootValidator() {\n let resolved: ResolvedConfigLike;\n let needMergeMessage: boolean;\n\n return {\n name: 'vite-plugin-vue-transition-root-validator',\n\n /**\n * 保存解析后的配置\n */\n configResolved(config: ResolvedConfigLike) {\n resolved = config;\n // 判断 Vite 版本:7 以下需要把 stack 合入 message\n const viteVersion = config.version;\n const viteMajorVersion = viteVersion ? parseInt(viteVersion.split('.')[0], 10) : 6;\n needMergeMessage = isNaN(viteMajorVersion) || viteMajorVersion < 7;\n },\n\n /**\n * 配置开发服务器\n * 监听客户端上报的警告消息,并通过 error overlay 显示\n */\n configureServer(server: DevServerLike) {\n if (resolved.command !== 'serve') return;\n\n // 用于去重,避免同一客户端重复发送相同消息\n const lastByClient = new WeakMap<object, string>();\n\n // 监听客户端上报的警告\n server.ws.on('vite-plugin-vue-transition-root-validator:vue-warn', (payload: ClientReportPayload, client: object) => {\n if (!payload?.message) return;\n\n // 去重处理\n const key = payload.key ?? payload.message.slice(0, 800);\n const prev = lastByClient.get(client as unknown as object);\n if (prev === key) {\n // 仍然回 ACK,避免客户端重试积压\n (client as any as DevClientLike)?.send?.('vite-plugin-vue-transition-root-validator:ack', { key });\n return;\n }\n lastByClient.set(client as unknown as object, key);\n\n const effectiveLang: Lang = payload.lang ?? 'en';\n\n // 发送错误覆盖层\n sendErrorOverlay({\n server,\n message: payload.message,\n lang: effectiveLang,\n client: client as any as DevClientLike,\n needMergeMessage\n });\n\n // 回 ACK,通知客户端该消息已被处理(用于清理重试队列)\n (client as any as DevClientLike)?.send?.('vite-plugin-vue-transition-root-validator:ack', { key });\n });\n },\n\n /**\n * 解析虚拟模块\n * 处理 'virtual:vue-transition-root-validator' 模块的导入\n */\n resolveId(id: string) {\n if (id === 'virtual:vue-transition-root-validator') {\n // 返回一个虚拟模块 ID,加上 \\0 前缀表示这是一个虚拟模块\n return '\\0virtual:vue-transition-root-validator';\n }\n return null;\n },\n\n /**\n * 加载虚拟模块\n * 返回虚拟模块的代码内容\n */\n load(id: string) {\n if (id === '\\0virtual:vue-transition-root-validator') {\n const clientEntryTs = fileURLToPath(new URL('./client.ts', import.meta.url));\n const clientEntryJs = fileURLToPath(new URL('./client.js', import.meta.url));\n const clientEntry = existsSync(clientEntryTs) ? clientEntryTs : clientEntryJs;\n const clientUrl = `/@fs/${clientEntry.replace(/\\\\/g, '/')}`;\n\n // 返回虚拟模块代码:重新导出 client.ts 的函数\n return `\n// 虚拟模块:vue-transition-root-validator\n// 此模块由 vite-plugin-vue-transition-root-validator 插件自动生成\n\nimport { setupVueRootValidator } from ${JSON.stringify(clientUrl)};\n\n// 重新导出函数\nexport { setupVueRootValidator };\n`;\n }\n return null;\n },\n\n closeBundle(options: any) {\n console.log('进入closeBundle', options);\n try {\n // 1. 获取 Vite 打包的输出目录(默认 dist,支持用户自定义配置)\n const outDir = options.config.build.outDir;\n // 拼接 HTML 文件的完整路径(默认打包生成 index.html,支持自定义 HTML 文件名)\n const htmlFilePath = path.resolve(process.cwd(), outDir, 'index.html');\n\n // 2. 先判断 HTML 文件是否存在(避免文件不存在导致写入报错)\n if (!fs.existsSync(htmlFilePath)) {\n console.log(`[空HTML插件] 未找到 HTML 文件:${htmlFilePath}`);\n return;\n }\n\n // 3. 执行你的「自定义判断逻辑」(这里是示例,你可替换为自己的业务判断)\n // 示例:比如判断打包环境是否为生产环境,或是否满足某个自定义条件\n const plugins = resolved.plugins || [];\n console.log('plugins', plugins);\n const hasSvgBuilder = plugins.some((p: any) => p.name === 'svgBuilder');\n\n\n\n if (!hasSvgBuilder) {\n const outDir = resolved.build?.outDir ?? 'dist';\n const root = resolved.root ?? process.cwd();\n const distDir = resolve(root, outDir);\n const indexHtmlPath = resolve(distDir, 'index.html');\n\n\n\n // 4. 满足条件,将 HTML 文件内容置空(写入空字符串)\n fs.writeFileSync(htmlFilePath, '', 'utf-8');\n console.log(`[空HTML插件] 已成功将 HTML 文件置空:${htmlFilePath}`);\n return;\n }\n\n console.log(`[空HTML插件] 不满足置空条件,跳过 HTML 置空`);\n\n } catch (error: any) {\n // 捕获异常,避免插件报错导致整个打包流程异常终止\n console.error(`[空HTML插件] 操作失败:`, error.message);\n }\n\n }\n };\n}\n\n\n"],"mappings":";;;;;;AASA,MAAM,eAAe;CACnB,IAAI;EACF,eAAe;EACf,mBAAmB;;;;;;;;;;;;;;;;;EAiBpB;CACD,IAAI;EACF,eAAe;EACf,mBAAmB;;;;;;;;;;;;;;;;;EAiBpB;CACF;AAiED,SAAgB,iBAAiB,MAAoB;AACnD,QAAO,aAAa,MAAM;;;;;;;;ACtE5B,SAAS,iBAAiB,MAAiH;CACzI,MAAM,EAAE,QAAQ,SAAS,MAAM,QAAQ,qBAAqB;CAI5D,MAAM,UAAU;EACd,MAAM;EACN,KAAK;GACH,SALgB,mBAAmB,GAAG,iBAAiB,KAAK,CAAC,IAAI,YAAY,iBAAiB,KAAK;GAMnG,OAAO;GACR;EACF;AAED,KAAI,QAAQ,MAAM;AAChB,SAAO,KAAK,QAAQ;AACpB;;AAGF,QAAO,GAAG,KAAK,QAAQ;;;;;;;;;;;;;;;;;;;;;AAiCzB,SAAwB,uCAAuC;CAC7D,IAAI;CACJ,IAAI;AAEJ,QAAO;EACL,MAAM;EAKN,eAAe,QAA4B;AACzC,cAAW;GAEX,MAAM,cAAc,OAAO;GAC3B,MAAM,mBAAmB,cAAc,SAAS,YAAY,MAAM,IAAI,CAAC,IAAI,GAAG,GAAG;AACjF,sBAAmB,MAAM,iBAAiB,IAAI,mBAAmB;;EAOnE,gBAAgB,QAAuB;AACrC,OAAI,SAAS,YAAY,QAAS;GAGlC,MAAM,+BAAe,IAAI,SAAyB;AAGlD,UAAO,GAAG,GAAG,uDAAuD,SAA8B,WAAmB;AACnH,QAAI,CAAC,SAAS,QAAS;IAGvB,MAAM,MAAM,QAAQ,OAAO,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAExD,QADa,aAAa,IAAI,OAA4B,KAC7C,KAAK;AAEhB,KAAC,QAAiC,OAAO,iDAAiD,EAAE,KAAK,CAAC;AAClG;;AAEF,iBAAa,IAAI,QAA6B,IAAI;IAElD,MAAM,gBAAsB,QAAQ,QAAQ;AAG5C,qBAAiB;KACf;KACA,SAAS,QAAQ;KACjB,MAAM;KACE;KACR;KACD,CAAC;AAGF,IAAC,QAAiC,OAAO,iDAAiD,EAAE,KAAK,CAAC;KAClG;;EAOJ,UAAU,IAAY;AACpB,OAAI,OAAO,wCAET,QAAO;AAET,UAAO;;EAOT,KAAK,IAAY;AACf,OAAI,OAAO,2CAA2C;IACpD,MAAM,gBAAgB,cAAc,IAAI,IAAI,eAAe,OAAO,KAAK,IAAI,CAAC;IAC5E,MAAM,gBAAgB,cAAc,IAAI,IAAI,eAAe,OAAO,KAAK,IAAI,CAAC;IAE5E,MAAM,YAAY,SADE,WAAW,cAAc,GAAG,gBAAgB,eAC1B,QAAQ,OAAO,IAAI;AAGzD,WAAO;;;;wCAIyB,KAAK,UAAU,UAAU,CAAC;;;;;;AAM5D,UAAO;;EAGT,YAAY,SAAc;AACxB,WAAQ,IAAI,iBAAiB,QAAQ;AACrC,OAAI;IAEF,MAAM,SAAS,QAAQ,OAAO,MAAM;IAEpC,MAAM,eAAe,KAAK,QAAQ,QAAQ,KAAK,EAAE,QAAQ,aAAa;AAGtE,QAAI,CAAC,GAAG,WAAW,aAAa,EAAE;AAChC,aAAQ,IAAI,yBAAyB,eAAe;AACpD;;IAKF,MAAM,UAAU,SAAS,WAAW,EAAE;AACtC,YAAQ,IAAI,WAAW,QAAQ;AAK/B,QAAI,CAJkB,QAAQ,MAAM,MAAW,EAAE,SAAS,aAAa,EAInD;KAClB,MAAMA,WAAS,SAAS,OAAO,UAAU;AAGnB,aADN,QADH,SAAS,QAAQ,QAAQ,KAAK,EACbA,SAAO,EACE,aAAa;AAKpD,QAAG,cAAc,cAAc,IAAI,QAAQ;AAC3C,aAAQ,IAAI,4BAA4B,eAAe;AACvD;;AAGF,YAAQ,IAAI,+BAA+B;YAEpC,OAAY;AAEnB,YAAQ,MAAM,mBAAmB,MAAM,QAAQ;;;EAIpD"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-check-multiple-dom",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.1.1-beta.2",
5
5
  "description": "Capture Vue <Transition> runtime warnings and show actionable overlay in Vite dev.",
6
6
  "keywords": [
7
7
  "azir",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-BFTbLKhl.d.cts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;AASkB;KAAb,aAAA,GA8EuD;MAiBhC;IAwET,IAAA,EAAA,CAAA,OAAA,EAAA;MAAK,IAAA,EAAA,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAzFA,oCAAA,CAAA;;;;;;;;;;0BAiBI;;;;;;;;;;;iBAwET"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DIr66WSZ.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;AASkB;KAAb,aAAA,GA8EuD;MAiBhC;IAwET,IAAA,EAAA,CAAA,OAAA,EAAA;MAAK,IAAA,EAAA,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAzFA,oCAAA,CAAA;;;;;;;;;;0BAiBI;;;;;;;;;;;iBAwET"}