vite-plugin-preloader 1.0.1 → 1.1.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.
package/dist/index.mjs CHANGED
@@ -2,153 +2,198 @@
2
2
 
3
3
  // src/runtime.ts
4
4
  var runtimeTemplate = `// \u{1F680} Auto-generated by vite-plugin-preloader
5
- import { ref, defineComponent, h, onMounted } from 'vue'
5
+ (function() {
6
+ 'use strict';
7
+
8
+ // \u{1F3AF} \u9884\u52A0\u8F7D\u914D\u7F6E\uFF08\u6784\u5EFA\u65F6\u6CE8\u5165\uFF09
9
+ const PRELOAD_ROUTES = __PRELOAD_ROUTES__
10
+ const PRELOAD_OPTIONS = __PRELOAD_OPTIONS__
6
11
 
7
- interface PreloadRoute {
8
- path: string
9
- component: () => Promise<any>
10
- reason: string
11
- priority: number
12
- }
12
+ class PreloaderManager {
13
+ constructor() {
14
+ this.preloadedRoutes = new Set()
15
+ this.isPreloading = false
16
+ this.stats = {
17
+ total: 0, completed: 0, failed: 0, startTime: 0, endTime: 0
18
+ }
19
+ this.statusElement = null
20
+ }
13
21
 
14
- interface PreloadStats {
15
- total: number
16
- completed: number
17
- failed: number
18
- startTime: number
19
- endTime: number
20
- }
22
+ async start() {
23
+ if (this.isPreloading) return
21
24
 
22
- // \u{1F3AF} \u9884\u52A0\u8F7D\u914D\u7F6E\uFF08\u6784\u5EFA\u65F6\u6CE8\u5165\uFF09
23
- const PRELOAD_ROUTES = __PRELOAD_ROUTES__
24
- const PRELOAD_OPTIONS = __PRELOAD_OPTIONS__
25
+ this.isPreloading = true
26
+ this.stats = {
27
+ total: PRELOAD_ROUTES.length,
28
+ completed: 0, failed: 0,
29
+ startTime: Date.now(), endTime: 0
30
+ }
25
31
 
26
- class PreloaderManager {
27
- private preloadedRoutes = new Set()
28
- private isPreloading = ref(false)
29
- private stats = ref({
30
- total: 0, completed: 0, failed: 0, startTime: 0, endTime: 0
31
- })
32
+ if (PRELOAD_OPTIONS.debug) {
33
+ console.log(\`\u{1F680} [\u9884\u52A0\u8F7D] \u5F00\u59CB\u9884\u52A0\u8F7D \${PRELOAD_ROUTES.length} \u4E2A\u9875\u9762\`)
34
+ }
32
35
 
33
- async start() {
34
- if (this.isPreloading.value) return
36
+ // \u663E\u793A\u72B6\u6001\u6307\u793A\u5668
37
+ this.showStatus()
35
38
 
36
- this.isPreloading.value = true
37
- this.stats.value = {
38
- total: PRELOAD_ROUTES.length,
39
- completed: 0, failed: 0,
40
- startTime: Date.now(), endTime: 0
39
+ const sortedRoutes = [...PRELOAD_ROUTES].sort((a, b) => a.priority - b.priority)
40
+
41
+ for (const route of sortedRoutes) {
42
+ await this.preloadSingle(route)
43
+ this.updateStatus()
44
+ await this.sleep(100)
45
+ }
46
+
47
+ this.stats.endTime = Date.now()
48
+ this.isPreloading = false
49
+
50
+ if (PRELOAD_OPTIONS.debug) {
51
+ console.log(\`\u{1F389} [\u9884\u52A0\u8F7D] \u5B8C\u6210! \u8017\u65F6 \${this.stats.endTime - this.stats.startTime}ms\`)
52
+ }
53
+
54
+ // \u9690\u85CF\u72B6\u6001\u6307\u793A\u5668
55
+ this.hideStatus()
41
56
  }
42
57
 
43
- console.log(\`\u{1F680} [\u9884\u52A0\u8F7D] \u5F00\u59CB\u9884\u52A0\u8F7D \${PRELOAD_ROUTES.length} \u4E2A\u9875\u9762\`)
58
+ async preloadSingle(route) {
59
+ if (this.preloadedRoutes.has(route.path)) return
44
60
 
45
- const sortedRoutes = [...PRELOAD_ROUTES].sort((a, b) => a.priority - b.priority)
46
-
47
- for (const route of sortedRoutes) {
48
- await this.preloadSingle(route)
49
- await this.sleep(100)
61
+ try {
62
+ const startTime = Date.now()
63
+ let componentPath = route.component
64
+
65
+ // \u5728\u5F00\u53D1\u73AF\u5883\u4E2D\uFF0CVite \u4F1A\u5904\u7406\u6A21\u5757\u89E3\u6790
66
+ // \u6211\u4EEC\u9700\u8981\u4F7F\u7528\u6B63\u786E\u7684\u6A21\u5757 ID
67
+ if (componentPath.startsWith('@/')) {
68
+ // \u5BF9\u4E8E Vite\uFF0C@ \u522B\u540D\u5E94\u8BE5\u5728\u6784\u5EFA\u65F6\u5C31\u88AB\u89E3\u6790
69
+ // \u4F46\u5728\u8FD0\u884C\u65F6\u6211\u4EEC\u9700\u8981\u4F7F\u7528\u5B9E\u9645\u7684\u8DEF\u5F84
70
+ componentPath = componentPath.replace('@/', '/src/')
71
+ }
72
+
73
+ // \u786E\u4FDD\u8DEF\u5F84\u4EE5 / \u5F00\u5934\uFF08\u76F8\u5BF9\u4E8E\u9879\u76EE\u6839\u76EE\u5F55\uFF09
74
+ if (!componentPath.startsWith('/') && !componentPath.startsWith('./')) {
75
+ componentPath = '/' + componentPath
76
+ }
77
+
78
+ if (PRELOAD_OPTIONS.debug) {
79
+ console.log(\`\u{1F50D} [\u9884\u52A0\u8F7D] \u5C1D\u8BD5\u52A0\u8F7D: \${componentPath}\`)
80
+ }
81
+
82
+ const module = await import(/* @vite-ignore */ componentPath)
83
+ const loadTime = Date.now() - startTime
84
+
85
+ this.preloadedRoutes.add(route.path)
86
+ this.stats.completed++
87
+
88
+ if (PRELOAD_OPTIONS.debug) {
89
+ console.log(\`\u2705 [\u9884\u52A0\u8F7D] \${route.path} (\${loadTime}ms) - \${route.reason}\`)
90
+ }
91
+ } catch (error) {
92
+ this.stats.failed++
93
+ if (PRELOAD_OPTIONS.debug) {
94
+ console.error(\`\u274C [\u9884\u52A0\u8F7D] \${route.path} \u5931\u8D25:\`, error)
95
+ }
96
+ }
50
97
  }
51
98
 
52
- this.stats.value.endTime = Date.now()
53
- this.isPreloading.value = false
54
-
55
- console.log(\`\u{1F389} [\u9884\u52A0\u8F7D] \u5B8C\u6210! \u8017\u65F6 \${this.stats.value.endTime - this.stats.value.startTime}ms\`)
56
- }
99
+ showStatus() {
100
+ if (!PRELOAD_OPTIONS.showStatus || !document.body) return
57
101
 
58
- async preloadSingle(route) {
59
- if (this.preloadedRoutes.has(route.path)) return
102
+ // \u6DFB\u52A0\u6837\u5F0F
103
+ if (!document.getElementById('preloader-styles')) {
104
+ const style = document.createElement('style')
105
+ style.id = 'preloader-styles'
106
+ const position = PRELOAD_OPTIONS.statusPosition.replace('-', ': 20px; ') + ': 20px;'
107
+ style.textContent = \`
108
+ .preloader-status {
109
+ position: fixed; \${position}
110
+ background: rgba(0,0,0,0.8); color: white; padding: 8px 16px;
111
+ border-radius: 6px; font-size: 12px; z-index: 9999;
112
+ pointer-events: none; font-family: system-ui;
113
+ transition: opacity 0.3s ease;
114
+ }
115
+ .preloader-status.fade-out {
116
+ opacity: 0;
117
+ }
118
+ \`
119
+ document.head.appendChild(style)
120
+ }
60
121
 
61
- try {
62
- const startTime = Date.now()
63
- await route.component()
64
- const loadTime = Date.now() - startTime
65
-
66
- this.preloadedRoutes.add(route.path)
67
- this.stats.value.completed++
68
- console.log(\`\u2705 [\u9884\u52A0\u8F7D] \${route.path} (\${loadTime}ms) - \${route.reason}\`)
69
- } catch (error) {
70
- this.stats.value.failed++
71
- console.error(\`\u274C [\u9884\u52A0\u8F7D] \${route.path} \u5931\u8D25:\`, error)
122
+ // \u521B\u5EFA\u72B6\u6001\u5143\u7D20
123
+ this.statusElement = document.createElement('div')
124
+ this.statusElement.className = 'preloader-status'
125
+ this.updateStatus()
126
+ document.body.appendChild(this.statusElement)
72
127
  }
73
- }
74
128
 
75
- sleep(ms) {
76
- return new Promise(resolve => setTimeout(resolve, ms))
77
- }
129
+ updateStatus() {
130
+ if (!this.statusElement) return
131
+ this.statusElement.textContent = \`\u{1F504} \u6B63\u5728\u4F18\u5316\u9875\u9762... \${this.stats.completed}/\${this.stats.total}\`
132
+ }
78
133
 
79
- isPreloaded(path) {
80
- return this.preloadedRoutes.has(path)
81
- }
134
+ hideStatus() {
135
+ if (!this.statusElement) return
136
+ this.statusElement.classList.add('fade-out')
137
+ setTimeout(() => {
138
+ if (this.statusElement && this.statusElement.parentNode) {
139
+ this.statusElement.parentNode.removeChild(this.statusElement)
140
+ }
141
+ }, 300)
142
+ }
82
143
 
83
- getStats() {
84
- return {
85
- ...this.stats.value,
86
- preloadedPaths: Array.from(this.preloadedRoutes),
87
- isPreloading: this.isPreloading.value
144
+ sleep(ms) {
145
+ return new Promise(resolve => setTimeout(resolve, ms))
88
146
  }
89
- }
90
147
 
91
- createStatusComponent() {
92
- const self = this
93
- return defineComponent({
94
- name: 'PreloadStatus',
95
- setup() {
96
- onMounted(() => {
97
- if (!document.getElementById('preloader-styles')) {
98
- const style = document.createElement('style')
99
- style.id = 'preloader-styles'
100
- const position = PRELOAD_OPTIONS.statusPosition.replace('-', ': 20px; ') + ': 20px;'
101
- style.textContent = \`
102
- .preloader-status {
103
- position: fixed; \${position}
104
- background: rgba(0,0,0,0.8); color: white; padding: 8px 16px;
105
- border-radius: 6px; font-size: 12px; z-index: 9999;
106
- pointer-events: none; font-family: system-ui;
107
- }
108
- \`
109
- document.head.appendChild(style)
110
- }
111
- })
148
+ isPreloaded(path) {
149
+ return this.preloadedRoutes.has(path)
150
+ }
112
151
 
113
- return () => {
114
- if (!self.isPreloading.value || !import.meta.env.DEV || !PRELOAD_OPTIONS.showStatus) {
115
- return null
116
- }
117
- return h('div', { class: 'preloader-status' }, [
118
- '\u{1F504} \u6B63\u5728\u4F18\u5316\u9875\u9762... ',
119
- \`\${self.stats.value.completed}/\${self.stats.value.total}\`
120
- ])
121
- }
152
+ getStats() {
153
+ return {
154
+ ...this.stats,
155
+ preloadedPaths: Array.from(this.preloadedRoutes),
156
+ isPreloading: this.isPreloading
122
157
  }
123
- })
158
+ }
124
159
  }
125
- }
126
160
 
127
- // \u{1F680} \u5168\u5C40\u5B9E\u4F8B
128
- const preloader = new PreloaderManager()
161
+ // \u{1F680} \u5168\u5C40\u5B9E\u4F8B
162
+ const preloader = new PreloaderManager()
163
+
164
+ // \u{1F6E0}\uFE0F \u5F00\u53D1\u73AF\u5883\u8C03\u8BD5\u5DE5\u5177
165
+ if (PRELOAD_OPTIONS.debug) {
166
+ window.preloaderDebug = {
167
+ stats: () => preloader.getStats(),
168
+ restart: () => preloader.start(),
169
+ check: (path) => preloader.isPreloaded(path),
170
+ help: () => console.log('\u{1F6E0}\uFE0F \u9884\u52A0\u8F7D\u8C03\u8BD5: stats() | restart() | check(path)')
171
+ }
172
+ console.log('\u{1F6E0}\uFE0F \u9884\u52A0\u8F7D\u8C03\u8BD5\u5DE5\u5177: window.preloaderDebug')
173
+ }
129
174
 
130
- // \u{1F6E0}\uFE0F \u5F00\u53D1\u73AF\u5883\u8C03\u8BD5\u5DE5\u5177
131
- if (import.meta.env.DEV && PRELOAD_OPTIONS.debug) {
132
- window.preloaderDebug = {
133
- stats: () => preloader.getStats(),
134
- restart: () => preloader.start(),
135
- check: (path) => preloader.isPreloaded(path),
136
- help: () => console.log('\u{1F6E0}\uFE0F \u9884\u52A0\u8F7D\u8C03\u8BD5: stats() | restart() | check(path)')
175
+ // \u{1F680} \u81EA\u52A8\u542F\u52A8 - \u7B49\u5F85 DOM \u52A0\u8F7D\u5B8C\u6210
176
+ function autoStart() {
177
+ if (document.readyState === 'loading') {
178
+ document.addEventListener('DOMContentLoaded', () => {
179
+ setTimeout(() => preloader.start(), PRELOAD_OPTIONS.delay)
180
+ })
181
+ } else {
182
+ setTimeout(() => preloader.start(), PRELOAD_OPTIONS.delay)
183
+ }
137
184
  }
138
- console.log('\u{1F6E0}\uFE0F \u9884\u52A0\u8F7D\u8C03\u8BD5\u5DE5\u5177: window.preloaderDebug')
139
- }
140
185
 
141
- // \u{1F3AF} \u5BFC\u51FA
142
- export const usePreloader = () => ({
143
- start: () => preloader.start(),
144
- isPreloaded: (path) => preloader.isPreloaded(path),
145
- StatusComponent: preloader.createStatusComponent()
146
- })
186
+ // \u7ACB\u5373\u6267\u884C\u81EA\u52A8\u542F\u52A8
187
+ autoStart()
147
188
 
148
- // \u{1F680} \u81EA\u52A8\u542F\u52A8
149
- if (typeof window !== 'undefined') {
150
- setTimeout(() => preloader.start(), PRELOAD_OPTIONS.delay || 2000)
151
- }`;
189
+ // \u5BFC\u51FA\u5230\u5168\u5C40\uFF08\u53EF\u9009\u4F7F\u7528\uFF09
190
+ window.usePreloader = () => ({
191
+ start: () => preloader.start(),
192
+ isPreloaded: (path) => preloader.isPreloaded(path),
193
+ getStats: () => preloader.getStats()
194
+ })
195
+
196
+ })();`;
152
197
 
153
198
  // src/generator.ts
154
199
  var CodeGenerator = class {
@@ -172,7 +217,7 @@ var CodeGenerator = class {
172
217
  const componentPath2 = this.inferComponentPath(route);
173
218
  return {
174
219
  path: route,
175
- component: `() => import('${componentPath2}')`,
220
+ component: componentPath2,
176
221
  reason: "\u81EA\u52A8\u63A8\u65AD\u7684\u9884\u52A0\u8F7D\u9875\u9762",
177
222
  priority: 2
178
223
  };
@@ -180,7 +225,7 @@ var CodeGenerator = class {
180
225
  const componentPath = route.component || this.inferComponentPath(route.path);
181
226
  return {
182
227
  path: route.path,
183
- component: `() => import('${componentPath}')`,
228
+ component: componentPath,
184
229
  reason: route.reason || "\u7528\u6237\u914D\u7F6E\u7684\u9884\u52A0\u8F7D\u9875\u9762",
185
230
  priority: route.priority || 2
186
231
  };
@@ -190,70 +235,77 @@ var CodeGenerator = class {
190
235
  * 处理选项配置
191
236
  */
192
237
  processOptions() {
238
+ const isDev = process.env.NODE_ENV !== "production";
193
239
  return {
194
- delay: this.options.delay || 2e3,
195
- showStatus: this.options.showStatus !== false,
196
- statusPosition: this.options.statusPosition || "bottom-right",
197
- debug: this.options.debug || false
240
+ delay: this.options.delay ?? 2e3,
241
+ // 默认2秒
242
+ showStatus: this.options.showStatus ?? true,
243
+ // 默认显示状态
244
+ statusPosition: this.options.statusPosition ?? "bottom-right",
245
+ // 默认右下角
246
+ debug: this.options.debug ?? isDev
247
+ // 开发环境默认开启调试,生产环境默认关闭
198
248
  };
199
249
  }
200
250
  /**
201
- * 推断组件路径
251
+ * 推断组件路径 - 使用 Vite 别名格式
202
252
  */
203
253
  inferComponentPath(routePath) {
204
- const cleanPath = routePath.replace(/^\//, "").replace(/\//g, "-");
205
- return `@/views/${cleanPath}/index.vue`;
254
+ const cleanPath = routePath.replace(/^\//, "");
255
+ if (cleanPath.startsWith("demo/")) {
256
+ return `@/views/${cleanPath}/index.vue`;
257
+ }
258
+ const pathSegments = cleanPath.split("/");
259
+ return `@/views/${pathSegments.join("/")}/index.vue`;
206
260
  }
207
261
  /**
208
- * 生成HTML注入代码
262
+ * 生成注入到 HTML 头部的脚本
209
263
  */
210
264
  generateHtmlInject() {
211
- if (this.options.showStatus === false) return "";
212
- return "<preloader-status></preloader-status>";
265
+ return `<script type="module">
266
+ ${this.generateRuntime()}
267
+ </script>`;
213
268
  }
214
269
  };
215
270
 
216
271
  // src/index.ts
217
- var VIRTUAL_MODULE_ID = "virtual:preloader";
218
- var RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
219
272
  function preloaderPlugin(options) {
220
273
  let generator;
274
+ const isDev = process.env.NODE_ENV !== "production";
275
+ const finalOptions = {
276
+ debug: isDev,
277
+ // 开发环境默认开启调试
278
+ delay: 2e3,
279
+ // 默认2秒
280
+ showStatus: true,
281
+ // 默认显示状态
282
+ statusPosition: "bottom-right",
283
+ // 默认右下角
284
+ ...options
285
+ // 用户配置覆盖默认配置
286
+ };
221
287
  return {
222
288
  name: "vite-plugin-preloader",
223
289
  // 🎯 设置插件执行顺序
224
290
  enforce: "post",
225
291
  configResolved() {
226
- generator = new CodeGenerator(options);
227
- console.log(`\u{1F680} \u9884\u52A0\u8F7D\u63D2\u4EF6\u5DF2\u542F\u7528\uFF0C\u914D\u7F6E\u4E86 ${options.routes.length} \u4E2A\u8DEF\u7531`);
228
- },
229
- resolveId(id) {
230
- if (id === VIRTUAL_MODULE_ID) {
231
- return RESOLVED_VIRTUAL_MODULE_ID;
232
- }
233
- return null;
234
- },
235
- load(id) {
236
- if (id === RESOLVED_VIRTUAL_MODULE_ID) {
237
- return generator.generateRuntime();
292
+ generator = new CodeGenerator(finalOptions);
293
+ if (finalOptions.debug) {
294
+ console.log(`\u{1F680} [\u9884\u52A0\u8F7D\u63D2\u4EF6] \u5DF2\u542F\u7528\uFF0C\u9884\u52A0\u8F7D ${finalOptions.routes.length} \u4E2A\u9875\u9762\uFF0C\u8BE6\u60C5\u8BF7\u67E5\u770B\u6D4F\u89C8\u5668\u63A7\u5236\u53F0`);
238
295
  }
239
- return null;
240
296
  },
241
- // 🎨 HTML 转换(修复类型错误)
297
+ // 🎨 HTML 转换 - 直接注入脚本到 HTML
242
298
  transformIndexHtml(html) {
243
299
  const inject = generator.generateHtmlInject();
244
- if (inject) {
245
- return html.replace(
246
- '<div id="app">',
247
- `<div id="app">
248
- ${inject}`
249
- );
250
- }
251
- return html;
300
+ return html.replace("</head>", `${inject}
301
+ </head>`);
252
302
  },
253
303
  // 🔥 HMR 支持
254
304
  handleHotUpdate(ctx) {
255
305
  if (ctx.file.includes("vite.config")) {
256
- console.log("\u{1F504} \u9884\u52A0\u8F7D\u914D\u7F6E\u5DF2\u66F4\u65B0");
306
+ if (finalOptions.debug) {
307
+ console.log("\u{1F504} [\u9884\u52A0\u8F7D\u63D2\u4EF6] \u914D\u7F6E\u5DF2\u66F4\u65B0");
308
+ }
257
309
  ctx.server.ws.send({
258
310
  type: "full-reload"
259
311
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime.ts","../src/generator.ts","../src/index.ts"],"sourcesContent":["// ============================================================================\r\n// ⚡ src/runtime.ts - 运行时代码模板(字符串)\r\n// ============================================================================\r\n\r\nexport const runtimeTemplate = `// 🚀 Auto-generated by vite-plugin-preloader\r\nimport { ref, defineComponent, h, onMounted } from 'vue'\r\n\r\ninterface PreloadRoute {\r\n path: string\r\n component: () => Promise<any>\r\n reason: string\r\n priority: number\r\n}\r\n\r\ninterface PreloadStats {\r\n total: number\r\n completed: number\r\n failed: number\r\n startTime: number\r\n endTime: number\r\n}\r\n\r\n// 🎯 预加载配置(构建时注入)\r\nconst PRELOAD_ROUTES = __PRELOAD_ROUTES__\r\nconst PRELOAD_OPTIONS = __PRELOAD_OPTIONS__\r\n\r\nclass PreloaderManager {\r\n private preloadedRoutes = new Set()\r\n private isPreloading = ref(false)\r\n private stats = ref({\r\n total: 0, completed: 0, failed: 0, startTime: 0, endTime: 0\r\n })\r\n\r\n async start() {\r\n if (this.isPreloading.value) return\r\n\r\n this.isPreloading.value = true\r\n this.stats.value = {\r\n total: PRELOAD_ROUTES.length,\r\n completed: 0, failed: 0,\r\n startTime: Date.now(), endTime: 0\r\n }\r\n\r\n console.log(\\`🚀 [预加载] 开始预加载 \\${PRELOAD_ROUTES.length} 个页面\\`)\r\n\r\n const sortedRoutes = [...PRELOAD_ROUTES].sort((a, b) => a.priority - b.priority)\r\n \r\n for (const route of sortedRoutes) {\r\n await this.preloadSingle(route)\r\n await this.sleep(100)\r\n }\r\n\r\n this.stats.value.endTime = Date.now()\r\n this.isPreloading.value = false\r\n \r\n console.log(\\`🎉 [预加载] 完成! 耗时 \\${this.stats.value.endTime - this.stats.value.startTime}ms\\`)\r\n }\r\n\r\n async preloadSingle(route) {\r\n if (this.preloadedRoutes.has(route.path)) return\r\n\r\n try {\r\n const startTime = Date.now()\r\n await route.component()\r\n const loadTime = Date.now() - startTime\r\n \r\n this.preloadedRoutes.add(route.path)\r\n this.stats.value.completed++\r\n console.log(\\`✅ [预加载] \\${route.path} (\\${loadTime}ms) - \\${route.reason}\\`)\r\n } catch (error) {\r\n this.stats.value.failed++\r\n console.error(\\`❌ [预加载] \\${route.path} 失败:\\`, error)\r\n }\r\n }\r\n\r\n sleep(ms) {\r\n return new Promise(resolve => setTimeout(resolve, ms))\r\n }\r\n\r\n isPreloaded(path) {\r\n return this.preloadedRoutes.has(path)\r\n }\r\n\r\n getStats() {\r\n return {\r\n ...this.stats.value,\r\n preloadedPaths: Array.from(this.preloadedRoutes),\r\n isPreloading: this.isPreloading.value\r\n }\r\n }\r\n\r\n createStatusComponent() {\r\n const self = this\r\n return defineComponent({\r\n name: 'PreloadStatus',\r\n setup() {\r\n onMounted(() => {\r\n if (!document.getElementById('preloader-styles')) {\r\n const style = document.createElement('style')\r\n style.id = 'preloader-styles'\r\n const position = PRELOAD_OPTIONS.statusPosition.replace('-', ': 20px; ') + ': 20px;'\r\n style.textContent = \\`\r\n .preloader-status {\r\n position: fixed; \\${position}\r\n background: rgba(0,0,0,0.8); color: white; padding: 8px 16px;\r\n border-radius: 6px; font-size: 12px; z-index: 9999;\r\n pointer-events: none; font-family: system-ui;\r\n }\r\n \\`\r\n document.head.appendChild(style)\r\n }\r\n })\r\n\r\n return () => {\r\n if (!self.isPreloading.value || !import.meta.env.DEV || !PRELOAD_OPTIONS.showStatus) {\r\n return null\r\n }\r\n return h('div', { class: 'preloader-status' }, [\r\n '🔄 正在优化页面... ',\r\n \\`\\${self.stats.value.completed}/\\${self.stats.value.total}\\`\r\n ])\r\n }\r\n }\r\n })\r\n }\r\n}\r\n\r\n// 🚀 全局实例\r\nconst preloader = new PreloaderManager()\r\n\r\n// 🛠️ 开发环境调试工具\r\nif (import.meta.env.DEV && PRELOAD_OPTIONS.debug) {\r\n window.preloaderDebug = {\r\n stats: () => preloader.getStats(),\r\n restart: () => preloader.start(),\r\n check: (path) => preloader.isPreloaded(path),\r\n help: () => console.log('🛠️ 预加载调试: stats() | restart() | check(path)')\r\n }\r\n console.log('🛠️ 预加载调试工具: window.preloaderDebug')\r\n}\r\n\r\n// 🎯 导出\r\nexport const usePreloader = () => ({\r\n start: () => preloader.start(),\r\n isPreloaded: (path) => preloader.isPreloaded(path),\r\n StatusComponent: preloader.createStatusComponent()\r\n})\r\n\r\n// 🚀 自动启动\r\nif (typeof window !== 'undefined') {\r\n setTimeout(() => preloader.start(), PRELOAD_OPTIONS.delay || 2000)\r\n}`","// ============================================================================\r\n// 🛠️ src/generator.ts - 代码生成器\r\n// ============================================================================\r\n\r\nimport type { PreloaderOptions } from './types'\r\nimport { runtimeTemplate } from './runtime'\r\n\r\nexport class CodeGenerator {\r\n constructor(private options: PreloaderOptions) {}\r\n\r\n /**\r\n * 生成运行时代码\r\n */\r\n generateRuntime(): string {\r\n const routes = this.processRoutes()\r\n const options = this.processOptions()\r\n\r\n return runtimeTemplate\r\n .replace('__PRELOAD_ROUTES__', JSON.stringify(routes, null, 2))\r\n .replace('__PRELOAD_OPTIONS__', JSON.stringify(options, null, 2))\r\n }\r\n\r\n /**\r\n * 处理路由配置\r\n */\r\n private processRoutes(): any[] {\r\n return this.options.routes.map(route => {\r\n // 处理字符串输入\r\n if (typeof route === 'string') {\r\n const componentPath = this.inferComponentPath(route)\r\n return {\r\n path: route,\r\n component: `() => import('${componentPath}')`,\r\n reason: '自动推断的预加载页面',\r\n priority: 2\r\n }\r\n }\r\n \r\n // 处理对象输入\r\n const componentPath = route.component || this.inferComponentPath(route.path)\r\n return {\r\n path: route.path,\r\n component: `() => import('${componentPath}')`,\r\n reason: route.reason || '用户配置的预加载页面',\r\n priority: route.priority || 2\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * 处理选项配置\r\n */\r\n private processOptions() {\r\n return {\r\n delay: this.options.delay || 2000,\r\n showStatus: this.options.showStatus !== false,\r\n statusPosition: this.options.statusPosition || 'bottom-right',\r\n debug: this.options.debug || false\r\n }\r\n }\r\n\r\n /**\r\n * 推断组件路径\r\n */\r\n private inferComponentPath(routePath: string): string {\r\n const cleanPath = routePath.replace(/^\\//, '').replace(/\\//g, '-')\r\n return `@/views/${cleanPath}/index.vue`\r\n }\r\n\r\n /**\r\n * 生成HTML注入代码\r\n */\r\n generateHtmlInject(): string {\r\n if (this.options.showStatus === false) return ''\r\n \r\n return '<preloader-status></preloader-status>'\r\n }\r\n}","// ============================================================================\r\n// 🚀 src/index.ts - 主插件文件\r\n// ============================================================================\r\n\r\nimport type { Plugin } from 'vite'\r\nimport type { PreloaderOptions } from './types'\r\nimport { CodeGenerator } from './generator'\r\n\r\nconst VIRTUAL_MODULE_ID = 'virtual:preloader'\r\nconst RESOLVED_VIRTUAL_MODULE_ID = '\\0' + VIRTUAL_MODULE_ID\r\n\r\nexport default function preloaderPlugin(options: PreloaderOptions): Plugin {\r\n let generator: CodeGenerator\r\n\r\n return {\r\n name: 'vite-plugin-preloader',\r\n \r\n // 🎯 设置插件执行顺序\r\n enforce: 'post',\r\n \r\n configResolved() {\r\n generator = new CodeGenerator(options)\r\n console.log(`🚀 预加载插件已启用,配置了 ${options.routes.length} 个路由`)\r\n },\r\n\r\n resolveId(id) {\r\n if (id === VIRTUAL_MODULE_ID) {\r\n return RESOLVED_VIRTUAL_MODULE_ID\r\n }\r\n return null // 🔧 修复:明确返回 null\r\n },\r\n\r\n load(id) {\r\n if (id === RESOLVED_VIRTUAL_MODULE_ID) {\r\n return generator.generateRuntime()\r\n }\r\n return null // 🔧 修复:明确返回 null\r\n },\r\n\r\n // 🎨 HTML 转换(修复类型错误)\r\n transformIndexHtml(html) {\r\n const inject = generator.generateHtmlInject()\r\n if (inject) {\r\n return html.replace(\r\n '<div id=\"app\">',\r\n `<div id=\"app\">\\n ${inject}`\r\n )\r\n }\r\n return html // 🔧 修复:确保总是返回 html\r\n },\r\n\r\n // 🔥 HMR 支持\r\n handleHotUpdate(ctx) {\r\n if (ctx.file.includes('vite.config')) {\r\n console.log('🔄 预加载配置已更新')\r\n ctx.server.ws.send({\r\n type: 'full-reload'\r\n })\r\n return []\r\n }\r\n return undefined // 🔧 修复:明确返回 undefined\r\n }\r\n }\r\n}\r\n\r\n// 命名导出,支持多种导入方式\r\nexport { type PreloaderOptions, type PreloadRoute } from './types'"],"mappings":"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","names":["componentPath"]}
1
+ {"version":3,"sources":["../src/runtime.ts","../src/generator.ts","../src/index.ts"],"sourcesContent":["// ============================================================================\r\n// ⚡ src/runtime.ts - 运行时代码模板(字符串)\r\n// ============================================================================\r\nexport const runtimeTemplate = `// 🚀 Auto-generated by vite-plugin-preloader\r\n(function() {\r\n 'use strict';\r\n \r\n // 🎯 预加载配置(构建时注入)\r\n const PRELOAD_ROUTES = __PRELOAD_ROUTES__\r\n const PRELOAD_OPTIONS = __PRELOAD_OPTIONS__\r\n\r\n class PreloaderManager {\r\n constructor() {\r\n this.preloadedRoutes = new Set()\r\n this.isPreloading = false\r\n this.stats = {\r\n total: 0, completed: 0, failed: 0, startTime: 0, endTime: 0\r\n }\r\n this.statusElement = null\r\n }\r\n\r\n async start() {\r\n if (this.isPreloading) return\r\n\r\n this.isPreloading = true\r\n this.stats = {\r\n total: PRELOAD_ROUTES.length,\r\n completed: 0, failed: 0,\r\n startTime: Date.now(), endTime: 0\r\n }\r\n\r\n if (PRELOAD_OPTIONS.debug) {\r\n console.log(\\`🚀 [预加载] 开始预加载 \\${PRELOAD_ROUTES.length} 个页面\\`)\r\n }\r\n\r\n // 显示状态指示器\r\n this.showStatus()\r\n\r\n const sortedRoutes = [...PRELOAD_ROUTES].sort((a, b) => a.priority - b.priority)\r\n \r\n for (const route of sortedRoutes) {\r\n await this.preloadSingle(route)\r\n this.updateStatus()\r\n await this.sleep(100)\r\n }\r\n\r\n this.stats.endTime = Date.now()\r\n this.isPreloading = false\r\n \r\n if (PRELOAD_OPTIONS.debug) {\r\n console.log(\\`🎉 [预加载] 完成! 耗时 \\${this.stats.endTime - this.stats.startTime}ms\\`)\r\n }\r\n\r\n // 隐藏状态指示器\r\n this.hideStatus()\r\n }\r\n\r\n async preloadSingle(route) {\r\n if (this.preloadedRoutes.has(route.path)) return\r\n\r\n try {\r\n const startTime = Date.now()\r\n let componentPath = route.component\r\n \r\n // 在开发环境中,Vite 会处理模块解析\r\n // 我们需要使用正确的模块 ID\r\n if (componentPath.startsWith('@/')) {\r\n // 对于 Vite,@ 别名应该在构建时就被解析\r\n // 但在运行时我们需要使用实际的路径\r\n componentPath = componentPath.replace('@/', '/src/')\r\n }\r\n \r\n // 确保路径以 / 开头(相对于项目根目录)\r\n if (!componentPath.startsWith('/') && !componentPath.startsWith('./')) {\r\n componentPath = '/' + componentPath\r\n }\r\n \r\n if (PRELOAD_OPTIONS.debug) {\r\n console.log(\\`🔍 [预加载] 尝试加载: \\${componentPath}\\`)\r\n }\r\n \r\n const module = await import(/* @vite-ignore */ componentPath)\r\n const loadTime = Date.now() - startTime\r\n \r\n this.preloadedRoutes.add(route.path)\r\n this.stats.completed++\r\n \r\n if (PRELOAD_OPTIONS.debug) {\r\n console.log(\\`✅ [预加载] \\${route.path} (\\${loadTime}ms) - \\${route.reason}\\`)\r\n }\r\n } catch (error) {\r\n this.stats.failed++\r\n if (PRELOAD_OPTIONS.debug) {\r\n console.error(\\`❌ [预加载] \\${route.path} 失败:\\`, error)\r\n }\r\n }\r\n }\r\n\r\n showStatus() {\r\n if (!PRELOAD_OPTIONS.showStatus || !document.body) return\r\n\r\n // 添加样式\r\n if (!document.getElementById('preloader-styles')) {\r\n const style = document.createElement('style')\r\n style.id = 'preloader-styles'\r\n const position = PRELOAD_OPTIONS.statusPosition.replace('-', ': 20px; ') + ': 20px;'\r\n style.textContent = \\`\r\n .preloader-status {\r\n position: fixed; \\${position}\r\n background: rgba(0,0,0,0.8); color: white; padding: 8px 16px;\r\n border-radius: 6px; font-size: 12px; z-index: 9999;\r\n pointer-events: none; font-family: system-ui;\r\n transition: opacity 0.3s ease;\r\n }\r\n .preloader-status.fade-out {\r\n opacity: 0;\r\n }\r\n \\`\r\n document.head.appendChild(style)\r\n }\r\n\r\n // 创建状态元素\r\n this.statusElement = document.createElement('div')\r\n this.statusElement.className = 'preloader-status'\r\n this.updateStatus()\r\n document.body.appendChild(this.statusElement)\r\n }\r\n\r\n updateStatus() {\r\n if (!this.statusElement) return\r\n this.statusElement.textContent = \\`🔄 正在优化页面... \\${this.stats.completed}/\\${this.stats.total}\\`\r\n }\r\n\r\n hideStatus() {\r\n if (!this.statusElement) return\r\n this.statusElement.classList.add('fade-out')\r\n setTimeout(() => {\r\n if (this.statusElement && this.statusElement.parentNode) {\r\n this.statusElement.parentNode.removeChild(this.statusElement)\r\n }\r\n }, 300)\r\n }\r\n\r\n sleep(ms) {\r\n return new Promise(resolve => setTimeout(resolve, ms))\r\n }\r\n\r\n isPreloaded(path) {\r\n return this.preloadedRoutes.has(path)\r\n }\r\n\r\n getStats() {\r\n return {\r\n ...this.stats,\r\n preloadedPaths: Array.from(this.preloadedRoutes),\r\n isPreloading: this.isPreloading\r\n }\r\n }\r\n }\r\n\r\n // 🚀 全局实例\r\n const preloader = new PreloaderManager()\r\n\r\n // 🛠️ 开发环境调试工具\r\n if (PRELOAD_OPTIONS.debug) {\r\n window.preloaderDebug = {\r\n stats: () => preloader.getStats(),\r\n restart: () => preloader.start(),\r\n check: (path) => preloader.isPreloaded(path),\r\n help: () => console.log('🛠️ 预加载调试: stats() | restart() | check(path)')\r\n }\r\n console.log('🛠️ 预加载调试工具: window.preloaderDebug')\r\n }\r\n\r\n // 🚀 自动启动 - 等待 DOM 加载完成\r\n function autoStart() {\r\n if (document.readyState === 'loading') {\r\n document.addEventListener('DOMContentLoaded', () => {\r\n setTimeout(() => preloader.start(), PRELOAD_OPTIONS.delay)\r\n })\r\n } else {\r\n setTimeout(() => preloader.start(), PRELOAD_OPTIONS.delay)\r\n }\r\n }\r\n\r\n // 立即执行自动启动\r\n autoStart()\r\n\r\n // 导出到全局(可选使用)\r\n window.usePreloader = () => ({\r\n start: () => preloader.start(),\r\n isPreloaded: (path) => preloader.isPreloaded(path),\r\n getStats: () => preloader.getStats()\r\n })\r\n\r\n})();`","// ============================================================================\r\n// 🛠️ src/generator.ts - 代码生成器\r\n// ============================================================================\r\nimport type { PreloaderOptions } from './types'\r\nimport { runtimeTemplate } from './runtime'\r\n\r\nexport class CodeGenerator {\r\n constructor(private options: PreloaderOptions) {}\r\n\r\n /**\r\n * 生成运行时代码\r\n */\r\n generateRuntime(): string {\r\n const routes = this.processRoutes();\r\n const options = this.processOptions();\r\n\r\n return runtimeTemplate\r\n .replace(\"__PRELOAD_ROUTES__\", JSON.stringify(routes, null, 2))\r\n .replace(\"__PRELOAD_OPTIONS__\", JSON.stringify(options, null, 2));\r\n }\r\n\r\n /**\r\n * 处理路由配置\r\n */\r\n private processRoutes(): any[] {\r\n return this.options.routes.map((route) => {\r\n // 处理字符串输入\r\n if (typeof route === \"string\") {\r\n const componentPath = this.inferComponentPath(route);\r\n return {\r\n path: route,\r\n component: componentPath,\r\n reason: \"自动推断的预加载页面\",\r\n priority: 2,\r\n };\r\n }\r\n\r\n // 处理对象输入\r\n const componentPath =\r\n route.component || this.inferComponentPath(route.path);\r\n return {\r\n path: route.path,\r\n component: componentPath,\r\n reason: route.reason || \"用户配置的预加载页面\",\r\n priority: route.priority || 2,\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * 处理选项配置\r\n */\r\n private processOptions() {\r\n // 智能默认配置\r\n const isDev = process.env.NODE_ENV !== \"production\";\r\n\r\n return {\r\n delay: this.options.delay ?? 2000, // 默认2秒\r\n showStatus: this.options.showStatus ?? true, // 默认显示状态\r\n statusPosition: this.options.statusPosition ?? \"bottom-right\", // 默认右下角\r\n debug: this.options.debug ?? isDev, // 开发环境默认开启调试,生产环境默认关闭\r\n };\r\n }\r\n\r\n /**\r\n * 推断组件路径 - 使用 Vite 别名格式\r\n */\r\n private inferComponentPath(routePath: string): string {\r\n const cleanPath = routePath.replace(/^\\//, \"\");\r\n\r\n // 直接使用 @ 别名,这在 Vite 构建后会被正确解析\r\n if (cleanPath.startsWith(\"demo/\")) {\r\n // /demo/13-calendar -> @/views/demo/13-calendar/index.vue\r\n return `@/views/${cleanPath}/index.vue`;\r\n }\r\n\r\n // 其他路径的处理\r\n const pathSegments = cleanPath.split(\"/\");\r\n return `@/views/${pathSegments.join(\"/\")}/index.vue`;\r\n }\r\n\r\n /**\r\n * 生成注入到 HTML 头部的脚本\r\n */\r\n generateHtmlInject(): string {\r\n return `<script type=\"module\">\r\n${this.generateRuntime()}\r\n</script>`;\r\n }\r\n}","import type { Plugin } from 'vite'\r\nimport type { PreloaderOptions } from './types'\r\nimport { CodeGenerator } from './generator'\r\n\r\nexport default function preloaderPlugin(options: PreloaderOptions): Plugin {\r\n let generator: CodeGenerator\r\n const isDev = process.env.NODE_ENV !== 'production'\r\n \r\n // 智能默认配置\r\n const finalOptions = {\r\n debug: isDev, // 开发环境默认开启调试\r\n delay: 2000, // 默认2秒\r\n showStatus: true, // 默认显示状态\r\n statusPosition: 'bottom-right' as const, // 默认右下角\r\n ...options // 用户配置覆盖默认配置\r\n }\r\n\r\n return {\r\n name: 'vite-plugin-preloader',\r\n \r\n // 🎯 设置插件执行顺序\r\n enforce: 'post',\r\n \r\n configResolved() {\r\n generator = new CodeGenerator(finalOptions)\r\n \r\n if (finalOptions.debug) {\r\n console.log(`🚀 [预加载插件] 已启用,预加载 ${finalOptions.routes.length} 个页面,详情请查看浏览器控制台`)\r\n }\r\n },\r\n\r\n // 🎨 HTML 转换 - 直接注入脚本到 HTML\r\n transformIndexHtml(html) {\r\n const inject = generator.generateHtmlInject()\r\n \r\n // 注入到 head 标签末尾\r\n return html.replace('</head>', `${inject}\\n</head>`)\r\n },\r\n\r\n // 🔥 HMR 支持\r\n handleHotUpdate(ctx) {\r\n if (ctx.file.includes('vite.config')) {\r\n if (finalOptions.debug) {\r\n console.log('🔄 [预加载插件] 配置已更新')\r\n }\r\n ctx.server.ws.send({\r\n type: 'full-reload'\r\n })\r\n return []\r\n }\r\n return undefined\r\n }\r\n }\r\n}\r\n\r\n// 命名导出,支持多种导入方式\r\nexport { type PreloaderOptions, type PreloadRoute } from './types'"],"mappings":"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","names":["componentPath"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-preloader",
3
- "version": "1.0.1",
3
+ "version": "1.1.2",
4
4
  "description": "🚀 Vite plugin for intelligent route preloading - 智能路由预加载插件",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",