@xysfe/vite-plugin-dev-proxy 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,230 +1,596 @@
1
1
  # @xysfe/vite-plugin-dev-proxy
2
2
 
3
- A Vite plugin for development environment proxy that automatically proxies remote server requests and handles HTML responses.
3
+ [![npm version](https://img.shields.io/npm/v/@xysfe/vite-plugin-dev-proxy.svg)](https://www.npmjs.com/package/@xysfe/vite-plugin-dev-proxy)
4
+ [![license](https://img.shields.io/npm/l/@xysfe/vite-plugin-dev-proxy.svg)](./LICENSE)
4
5
 
5
- ## Features
6
+ 一个强大的开发环境代理插件,支持 **Vite** 和 **Vue CLI**,用于代理远程服务器并自动注入本地开发代码。
6
7
 
7
- - 🚀 Automatically proxy remote server requests
8
- - 📦 Smart HTML response handling, replacing remote scripts and stylesheets with local development versions
9
- - 🍪 Automatic cookie rewriting, removing Secure and Domain attributes
10
- - 🔀 Redirect handling with protocol mismatch fixes
11
- - ⚙️ Support for custom static resource prefixes
12
- - 🎯 Flexible script/link tag filtering with string, array, regex, or function
13
- - 🏷️ Custom placeholder replacement for development script injection
14
- - 🐛 Debug logging support
15
- - 🔗 Merge with other proxy configurations
16
- - 🔧 TypeScript support with full type definitions
8
+ [English](./README.en.md) | 简体中文
17
9
 
18
- ## Installation
10
+ ## ✨ 特性
19
11
 
20
- ```bash
21
- npm install @xysfe/vite-plugin-dev-proxy --save-dev
22
- ```
12
+ - 🚀 **双框架支持** - 同时支持 Vite 和 Vue CLI
13
+ - 🔄 **智能代理** - 自动代理远程服务器的 HTML、API 等请求
14
+ - 💉 **脚本注入** - 自动注入本地入口脚本到远程 HTML
15
+ - 🧹 **脚本清理** - 灵活清除远程 HTML 中不需要的脚本和样式
16
+ - 🍪 **Cookie 处理** - 自动重写 Cookie,解决本地开发跨域问题
17
+ - 🔀 **重定向处理** - 智能处理 HTTP 重定向,自动转换为本地地址
18
+ - 🗜️ **解压缩支持** - 支持 gzip、deflate、brotli 压缩格式
19
+ - 🔌 **WebSocket 热更新** - 自动识别并排除 HMR WebSocket,无需手动配置
20
+ - 🎯 **灵活配置** - 支持字符串、数组、函数、正则等多种配置方式
21
+ - 📦 **零依赖** - 核心功能无外部依赖
22
+ - 🔧 **TypeScript** - 完整的类型定义和 JSDoc 注释
23
+ - 🐛 **调试模式** - 详细的日志输出,方便排查问题
23
24
 
24
- ```bash
25
- yarn add @xysfe/vite-plugin-dev-proxy --dev
26
- ```
25
+ ## 📦 安装
27
26
 
28
27
  ```bash
29
- pnpm add @xysfe/vite-plugin-dev-proxy --save-dev
28
+ # npm
29
+ npm install @xysfe/vite-plugin-dev-proxy -D
30
+
31
+ # yarn
32
+ yarn add @xysfe/vite-plugin-dev-proxy -D
33
+
34
+ # pnpm
35
+ pnpm add @xysfe/vite-plugin-dev-proxy -D
30
36
  ```
31
37
 
32
- ## Usage
38
+ ## 🚀 快速开始
33
39
 
34
- ### Basic Usage
40
+ ### Vite 项目
35
41
 
36
- ```js
42
+ ```javascript
37
43
  // vite.config.js
38
44
  import { defineConfig } from "vite";
39
- import viteDevProxy from "@xysfe/vite-plugin-dev-proxy";
45
+ import { VitePluginDevProxy } from "@xysfe/vite-plugin-dev-proxy";
40
46
 
41
47
  export default defineConfig({
42
48
  plugins: [
43
- viteDevProxy({
44
- appHost: "example.com",
49
+ VitePluginDevProxy({
50
+ appHost: "example.com", // 远程服务器地址(必填)
51
+ https: true, // 使用 HTTPS
52
+ entry: "/src/main.js", // 本地入口文件
53
+ staticPrefix: "/dev/static", // 静态资源前缀
54
+ remotePrefixes: ["/static/component"], // 远程资源路径
55
+ clearScriptCssPrefixes: "/static", // 清除远程脚本/样式
56
+ debug: true, // 开启调试日志
45
57
  }),
46
58
  ],
47
59
  });
48
60
  ```
49
61
 
50
- ### Full Configuration
62
+ ### Vue CLI 项目
51
63
 
52
- ```js
53
- // vite.config.js
54
- import { defineConfig } from "vite";
55
- import viteDevProxy from "@xysfe/vite-plugin-dev-proxy";
64
+ ```javascript
65
+ // vue.config.js
66
+ const { VueCliPluginDevProxy } = require("@xysfe/vite-plugin-dev-proxy");
56
67
 
57
- export default defineConfig({
58
- plugins: [
59
- viteDevProxy({
60
- appHost: "example.com",
61
- https: true,
62
- staticPrefix: "/dev/static",
63
- bypassPrefixes: ["/static"],
64
- clearScriptCssPrefixes: "/static/global",
65
- developmentAgentOccupancy:
66
- "<!-- Vite development mode proxy occupancy -->",
67
- entry: "/src/main.js",
68
- debug: true,
69
- }),
70
- ],
68
+ module.exports = VueCliPluginDevProxy({
69
+ appHost: "example.com",
70
+ https: true,
71
+ entry: ["/js/chunk-vendors.js", "/js/app.js"],
72
+ staticPrefix: "/dev/static",
73
+ remotePrefixes: ["/static/component"],
74
+ clearScriptCssPrefixes: "/static",
75
+ debug: true,
71
76
  });
72
77
  ```
73
78
 
74
- ### Advanced Usage: Custom Script/Link Filtering
79
+ ## 📚 配置选项
75
80
 
76
- ```js
77
- // vite.config.js
78
- import { RegeExp } from "vite";
79
- import viteDevProxy from "@xysfe/vite-plugin-dev-proxy";
81
+ ### ProxyOptions
80
82
 
81
- export default defineConfig({
82
- plugins: [
83
- viteDevProxy({
84
- appHost: "example.com",
85
- // Filter by string prefix
86
- clearScriptCssPrefixes: "/static/global",
87
- // Or filter by multiple prefixes
88
- clearScriptCssPrefixes: ["/static/global", "/cdn/assets"],
89
- // Or filter by regex
90
- clearScriptCssPrefixes: /cdn\.example\.com/,
91
- // Or filter by custom function
92
- clearScriptCssPrefixes: (match) => {
93
- return match.includes("remove-me");
94
- },
95
- }),
96
- ],
83
+ | 参数 | 类型 | 默认值 | 说明 |
84
+ | --------------------------- | ------------------------------------------ | --------------------------------------------------------------------------- | -------------------------------------------- |
85
+ | `appHost` | `string` | - | **必填**。远程服务器地址,如 `'example.com'` |
86
+ | `https` | `boolean` | `true` | 是否使用 HTTPS 协议 |
87
+ | `staticPrefix` | `string` | `'/dev/static'` | 静态资源路径前缀,用于构建本地资源路径 |
88
+ | `remotePrefixes` | `string \| string[] \| Function \| RegExp` | `['/static/component']` | 远程资源路径规则,匹配的资源从远程加载 |
89
+ | `clearScriptCssPrefixes` | `string \| string[] \| Function \| RegExp` | `''` | 清除脚本/CSS 的规则,匹配的标签会被移除 |
90
+ | `entry` | `string \| string[]` | Vite: `'/src/main.js'`<br>Vue CLI: `['/js/chunk-vendors.js', '/js/app.js']` | 本地入口文件路径,支持单个或多个 |
91
+ | `developmentAgentOccupancy` | `string` | `''` | 自定义占位符,用于替换为入口脚本 |
92
+ | `localIndexHtml` | `string` | `''` | 本地 HTML 文件路径(库模式使用) |
93
+ | `debug` | `boolean` | `false` | 是否开启调试模式,输出详细日志 |
94
+
95
+ ## 🎯 高级用法
96
+
97
+ ### 1. remotePrefixes - 远程资源路径配置
98
+
99
+ `remotePrefixes` 用于指定哪些资源应该从远程服务器加载,支持 4 种类型:
100
+
101
+ #### 字符串类型(单个前缀)
102
+
103
+ ```javascript
104
+ VitePluginDevProxy({
105
+ appHost: "example.com",
106
+ remotePrefixes: "/static/component", // 字符串
97
107
  });
98
108
  ```
99
109
 
100
- ### Coexisting with Other Proxy Configurations
110
+ **匹配规则**:URL `/static/component` 开头的资源从远程加载。
101
111
 
102
- ```js
103
- // vite.config.js
104
- export default defineConfig({
105
- plugins: [
106
- viteDevProxy({
107
- appHost: "example.com",
108
- }),
109
- ],
110
- server: {
111
- proxy: {
112
- "/api": {
113
- target: "http://localhost:8080",
114
- },
115
- },
112
+ **示例**:
113
+
114
+ - `/static/component/button.js` → 远程加载
115
+ - ✅ `/static/component/styles/main.css` → 远程加载
116
+ - ❌ `/static/images/logo.png` → 本地加载
117
+
118
+ #### 数组类型(多个前缀)
119
+
120
+ ```javascript
121
+ VitePluginDevProxy({
122
+ appHost: "example.com",
123
+ remotePrefixes: ["/static/component", "/static/lib", "/api"], // 数组
124
+ });
125
+ ```
126
+
127
+ **匹配规则**:URL 以数组中任一前缀开头的资源从远程加载。
128
+
129
+ #### 正则表达式类型
130
+
131
+ ```javascript
132
+ VitePluginDevProxy({
133
+ appHost: "example.com",
134
+ remotePrefixes: /^\/static\/(?!images)/, // 正则:排除 images 文件夹
135
+ });
136
+ ```
137
+
138
+ **更多正则示例**:
139
+
140
+ ```javascript
141
+ // 匹配所有 .min.js 文件
142
+ remotePrefixes: /\.min\.js$/;
143
+ // 匹配 /api/ 或 /services/ 开头的路径
144
+ remotePrefixes: /^\/(api|services)\//;
145
+ // 匹配包含版本号的资源
146
+ remotePrefixes: /\/lib\/v\d+\.\d+\.\d+\//;
147
+ ```
148
+
149
+ #### 函数类型(自定义逻辑)
150
+
151
+ ```javascript
152
+ VitePluginDevProxy({
153
+ appHost: "example.com",
154
+ remotePrefixes: (url) => {
155
+ // 微前端场景:子应用使用远程资源
156
+ const microApps = ["/micro-app-1/", "/micro-app-2/"];
157
+ return microApps.some((app) => url.startsWith(app));
116
158
  },
117
159
  });
118
160
  ```
119
161
 
120
- ## API
162
+ **函数签名**:`(url: string) => boolean`
163
+
164
+ - 参数 `url`:完整的请求 URL
165
+ - 返回 `true`:从远程加载
166
+ - 返回 `false`:使用本地资源
167
+
168
+ **更多函数示例**:
169
+
170
+ ```javascript
171
+ // 根据环境变量决定
172
+ remotePrefixes: (url) => {
173
+ return process.env.USE_REMOTE === "true" && url.startsWith("/static");
174
+ };
175
+
176
+ // 复杂的业务逻辑
177
+ remotePrefixes: (url) => {
178
+ if (url.startsWith("/modules/payment/")) return true;
179
+ if (url.startsWith("/modules/checkout/")) return true;
180
+ if (url.includes("/vendor/")) return true;
181
+ return false;
182
+ };
183
+ ```
184
+
185
+ ### 2. clearScriptCssPrefixes - 清除远程脚本/样式
186
+
187
+ `clearScriptCssPrefixes` 用于清除远程 HTML 中不需要的 `<script>` 和 `<link>` 标签,同样支持 4 种类型:
188
+
189
+ #### 字符串类型
190
+
191
+ ```javascript
192
+ VitePluginDevProxy({
193
+ appHost: "example.com",
194
+ clearScriptCssPrefixes: "/static", // 清除 src/href 以 /static 开头的标签
195
+ });
196
+ ```
197
+
198
+ #### 数组类型
121
199
 
122
- ### `viteDevProxy(options?)`
200
+ ```javascript
201
+ VitePluginDevProxy({
202
+ appHost: "example.com",
203
+ clearScriptCssPrefixes: ["/static", "/vendor"], // 清除多个前缀
204
+ });
205
+ ```
123
206
 
124
- #### Options
207
+ #### 正则表达式类型
125
208
 
126
- | Parameter | Type | Default | Required | Description |
127
- | --------------------------- | ------------------------------------------ | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
128
- | `appHost` | `string` | - | ✅ | Target server address |
129
- | `https` | `boolean` | `true` | - | Whether to be HTTPS for the target server |
130
- | `staticPrefix` | `string` | `''` | - | Static resource prefix, used to build local entry path |
131
- | `bypassPrefixes` | `string[]` | `['/static']` | - | List of prefixes to bypass proxy, requests matching these prefixes will access remote resources |
132
- | `clearScriptCssPrefixes` | `string \| string[] \| RegExp \| Function` | `''` | - | Filter script/link tags to remove. Supports string prefix, array of prefixes, regex, or custom function |
133
- | `developmentAgentOccupancy` | `string` | `''` | - | Custom placeholder string to replace with local development script. If not set, script will be injected into div with id="app" |
134
- | `entry` | `string` | `'/src/main.js'` | - | Local development entry file path |
135
- | `isLib` | `boolean` | `false` | - | Whether in component library mode, returns local HTML file when true |
136
- | `localIndexHtml` | `string` | `'index.html'` | - | Local HTML file path (only used when isLib=true) |
137
- | `debug` | `boolean` | `false` | - | Whether to enable debug logging |
209
+ ```javascript
210
+ VitePluginDevProxy({
211
+ appHost: "example.com",
212
+ clearScriptCssPrefixes: /\.(min\.js|min\.css)$/, // 清除压缩文件
213
+ });
214
+ ```
138
215
 
139
- ## How It Works
216
+ #### 函数类型
140
217
 
141
- ### 1. Proxy Configuration
218
+ ```javascript
219
+ VitePluginDevProxy({
220
+ appHost: "example.com",
221
+ clearScriptCssPrefixes: (tag) => {
222
+ // 清除包含 'legacy' 的标签
223
+ return tag.includes("legacy");
224
+ },
225
+ });
226
+ ```
142
227
 
143
- The plugin injects `server.proxy` configuration through Vite's `config` hook, proxying all requests to the target server.
228
+ **函数签名**:`(tag: string) => boolean`
144
229
 
145
- ### 2. HTML Processing
230
+ - 参数 `tag`:完整的 HTML 标签字符串
231
+ - 返回 `true`:清除该标签
232
+ - 返回 `false`:保留该标签
146
233
 
147
- When detecting a browser page navigation request and the response is HTML:
234
+ ### 3. 多入口配置
148
235
 
149
- - Matches all `<script>` and `<link>` tags in the HTML
150
- - Removes tags based on `clearScriptCssPrefixes` configuration:
151
- - If string: removes tags where src/href starts with the prefix
152
- - If array: removes tags where src/href starts with any of the prefixes
153
- - If RegExp: removes tags matching the regex pattern
154
- - If Function: removes tags where the function returns true
155
- - Inserts local development script entry:
156
- - If `developmentAgentOccupancy` is set, replaces that placeholder with the local script
157
- - Otherwise, injects the local script into `<div id="app">` element
236
+ 支持单个或多个入口文件:
158
237
 
159
- ### 3. Cookie Rewriting
238
+ ```javascript
239
+ // 单入口
240
+ VitePluginDevProxy({
241
+ appHost: "example.com",
242
+ entry: "/src/main.js",
243
+ });
160
244
 
161
- Automatically removes `Secure`, `Domain`, and `SameSite` attributes from cookies to ensure proper functioning in the local development environment.
245
+ // 多入口(会按顺序注入)
246
+ VitePluginDevProxy({
247
+ appHost: "example.com",
248
+ entry: ["/src/vendors.js", "/src/polyfills.js", "/src/main.js"],
249
+ });
250
+ ```
162
251
 
163
- ### 4. Redirect Handling
252
+ 生成的 HTML:
164
253
 
165
- - Replaces remote domain names in redirect URLs with local domain names
166
- - Fixes protocol mismatch issues (https://localhost -> http://localhost)
254
+ ```html
255
+ <script crossorigin type="module" src="/dev/static/src/vendors.js"></script>
256
+ <script crossorigin type="module" src="/dev/static/src/polyfills.js"></script>
257
+ <script crossorigin type="module" src="/dev/static/src/main.js"></script>
258
+ ```
167
259
 
168
- ## Debugging
260
+ ### 4. 自定义占位符
169
261
 
170
- Enable the `debug` option to view detailed logs:
262
+ 使用自定义占位符精确控制脚本注入位置:
171
263
 
172
- ```js
173
- viteDevProxy({
264
+ ```javascript
265
+ VitePluginDevProxy({
174
266
  appHost: "example.com",
175
- debug: true,
267
+ developmentAgentOccupancy: "<!-- DEV_ENTRY -->",
268
+ entry: "/src/main.js",
176
269
  });
177
270
  ```
178
271
 
179
- Log output example:
272
+ 远程 HTML:
180
273
 
274
+ ```html
275
+ <body>
276
+ <div id="app"></div>
277
+ <!-- DEV_ENTRY -->
278
+ </body>
181
279
  ```
182
- @xysfe/vite-plugin-dev-proxy: staticPrefix /dev/static
183
- Proxy request: /admin/index (5ms)
184
- HTML processed: /admin/index (23ms)
185
- Bypass proxy: /static/js/app.js
186
- Redirect handled: https://example.com/login -> http://localhost:3003/login (3ms)
280
+
281
+ 处理后:
282
+
283
+ ```html
284
+ <body>
285
+ <div id="app"></div>
286
+ <script crossorigin type="module" src="/dev/static/src/main.js"></script>
287
+ </body>
288
+ ```
289
+
290
+ 如果不设置占位符,脚本会自动注入到 `<div id="app">` 后面。
291
+
292
+ ### 5. 库模式
293
+
294
+ 开发组件库时,直接使用本地 HTML 文件:### 5. 库模式
295
+
296
+ ```javascript
297
+ VitePluginDevProxy({
298
+ appHost: "example.com",
299
+ localIndexHtml: "./public/index.html",
300
+ });
301
+ ```
302
+
303
+ ## 📖 使用场景
304
+
305
+ ### 场景 2:渐进式迁移
306
+
307
+ ```javascript
308
+ VitePluginDevProxy({
309
+ appHost: "legacy.com",
310
+ // 已迁移的模块使用本地,未迁移的使用远程
311
+ remotePrefixes: (url) => {
312
+ const migratedModules = ["/modules/user/", "/modules/product/"];
313
+ return !migratedModules.some((m) => url.startsWith(m));
314
+ },
315
+ entry: "/src/main.js",
316
+ });
317
+ ```
318
+
319
+ ### 场景 3:组件库开发
320
+
321
+ ```javascript
322
+ VitePluginDevProxy({
323
+ appHost: "showcase.com",
324
+ localIndexHtml: "./examples/index.html",
325
+ // 清除远程组件库的脚本
326
+ clearScriptCssPrefixes: /^\/lib\//,
327
+ entry: "/src/index.js",
328
+ });
329
+ ```
330
+
331
+ ### 场景 4:A/B 测试
332
+
333
+ ```javascript
334
+ VitePluginDevProxy({
335
+ appHost: "example.com",
336
+ // 根据条件决定使用本地还是远程
337
+ remotePrefixes: (url) => {
338
+ if (!url.startsWith("/components/")) return false;
339
+
340
+ // 50% 的流量使用远程组件
341
+ const userId = getUserId();
342
+ return userId % 2 === 0;
343
+ },
344
+ });
345
+ ```
346
+
347
+ ## 🔍 调试
348
+
349
+ 开启 `debug` 模式查看详细日志:
350
+
351
+ ```javascript
352
+ VitePluginDevProxy({
353
+ appHost: "example.com",
354
+ debug: true, // 开启调试
355
+ });
356
+ ```
357
+
358
+ **控制台输出示例**:
359
+
360
+ ```
361
+ vite-plugin-dev-proxy: staticPrefix /dev/static
362
+ [shouldUseLocal] /src/main.js
363
+ [Proxy] /static/component/button.js
364
+ Redirect handled: https://example.com/login -> http://localhost:5173/login (15ms)
365
+ HTML processed: /dashboard (342ms)
366
+ dev-proxy: rewrittenCookie token=xxx
367
+ ```
368
+
369
+ ## 🛠️ 工作原理
370
+
371
+ ### 流程图
372
+
373
+ ```
374
+ ┌─────────────────┐
375
+ │ 浏览器请求 │
376
+ └────────┬────────┘
377
+
378
+
379
+ ┌─────────────────┐
380
+ │ 判断资源类型 │
381
+ └────────┬────────┘
382
+
383
+ ┌────┴────┐
384
+ │ │
385
+ ▼ ▼
386
+ ┌────────┐ ┌────────┐
387
+ │ 本地资源│ │ 远程资源│
388
+ └────────┘ └───┬────┘
389
+
390
+ ┌────┴────┐
391
+ │ │
392
+ ▼ ▼
393
+ ┌────────┐ ┌────────┐
394
+ │ HTML │ │ 其他 │
395
+ └───┬────┘ └────────┘
396
+
397
+
398
+ ┌────────────────────┐
399
+ │ 1. 解压缩内容 │
400
+ │ 2. 清除远程脚本 │
401
+ │ 3. 注入本地脚本 │
402
+ │ 4. 重写 Cookie │
403
+ │ 5. 处理重定向 │
404
+ └────────────────────┘
187
405
  ```
188
406
 
189
- ## TypeScript Support
407
+ ### 详细说明
190
408
 
191
- This plugin is written in TypeScript and provides full type definitions. You can import types for better development experience:
409
+ 1. **请求拦截**:拦截所有开发服务器请求
410
+ 2. **资源判断**:根据 `remotePrefixes` 判断使用本地还是远程资源
411
+ 3. **HTML 处理**:
412
+ - 代理远程 HTML
413
+ - 解压缩内容(gzip/deflate/br)
414
+ - 根据 `clearScriptCssPrefixes` 清除指定标签
415
+ - 注入本地入口脚本
416
+ - 重写 Cookie 和重定向
417
+ 4. **其他资源**:直接代理或使用本地资源
418
+
419
+ ### Cookie 重写
420
+
421
+ 自动移除 Cookie 的 `secure`、`domain`、`samesite` 属性:
422
+
423
+ ```javascript
424
+ // 原始 Cookie
425
+ Set-Cookie: token=xxx; Domain=example.com; Secure; SameSite=Strict
426
+
427
+ // 重写后
428
+ Set-Cookie: token=xxx
429
+ ```
430
+
431
+ ### 重定向处理
432
+
433
+ 自动将远程重定向转换为本地重定向:
434
+
435
+ ```javascript
436
+ // 原始重定向
437
+ Location: https://example.com/dashboard
438
+
439
+ // 转换后
440
+ Location: http://localhost:5173/dashboard
441
+ ```
442
+
443
+ ## 📁 项目结构
444
+
445
+ ```
446
+ src/
447
+ ├── core.ts # 核心共享逻辑(~500 行)
448
+ │ ├── 类型定义 (ProxyOptions, IncomingMessage, etc.)
449
+ │ ├── 常量配置 (正则表达式、状态码等)
450
+ │ ├── 工具函数 (20+ 个纯函数)
451
+ │ │ ├── createLogger - 创建日志函数
452
+ │ │ ├── normalizePath - 路径标准化
453
+ │ │ ├── generateEntryScript - 生成入口脚本
454
+ │ │ ├── rewriteCookies - Cookie 重写
455
+ │ │ ├── decompressBuffer - 解压缩
456
+ │ │ ├── shouldClearScriptCss - 判断是否清除标签
457
+ │ │ ├── injectEntryScript - 注入脚本
458
+ │ │ ├── clearScriptCssTags - 清除标签
459
+ │ │ ├── isRedirectResponse - 判断重定向
460
+ │ │ ├── shouldProcessAsHtml - 判断处理HTML
461
+ │ │ ├── matchesRemoteResource - 匹配远程资源
462
+ │ │ ├── shouldUseLocal - 判断使用本地
463
+ │ │ ├── handleRedirect - 处理重定向
464
+ │ │ ├── handleLibModeHtml - 处理库模式HTML
465
+ │ │ ├── handleHtmlResponse - 处理HTML响应
466
+ │ │ ├── validateOptions - 验证配置
467
+ │ │ └── processOptions - 处理配置
468
+ │ └── 导出所有公共功能
469
+
470
+ ├── vite-cli.ts # Vite 插件(~160 行)
471
+ │ ├── VitePluginDevProxy - 默认导出
472
+ │ ├── createProxyConfig - 创建代理配置
473
+ │ └── 使用 core.ts 的工具函数
474
+
475
+ ├── vue-cli-plugin-dev-proxy.ts # Vue CLI 插件(~180 行)
476
+ │ ├── VueCliPluginDevProxy - 默认导出
477
+ │ ├── createProxyConfig - 创建代理配置
478
+ │ ├── onProxyReq, onError, onProxyRes 钩子
479
+ │ └── 使用 core.ts 的工具函数
480
+
481
+ └── index.ts # 入口文件
482
+ ├── export VitePluginDevProxy
483
+ └── export VueCliPluginDevProxy
484
+ ```
485
+
486
+ ## 📝 TypeScript 支持
487
+
488
+ 完整的 TypeScript 类型定义和 JSDoc 注释:
192
489
 
193
490
  ```typescript
194
- import viteDevProxy, { ProxyOptions } from "@xysfe/vite-plugin-dev-proxy";
491
+ import { VitePluginDevProxy } from "@xysfe/vite-plugin-dev-proxy";
492
+ import type { ProxyOptions } from "@xysfe/vite-plugin-dev-proxy/dist/core";
195
493
 
196
494
  const config: ProxyOptions = {
197
495
  appHost: "example.com",
198
496
  https: true,
497
+ entry: "/src/main.js",
498
+ remotePrefixes: ["/static/component"],
499
+ clearScriptCssPrefixes: (tag: string) => tag.includes("legacy"),
199
500
  debug: true,
200
501
  };
201
502
 
202
503
  export default defineConfig({
203
- plugins: [viteDevProxy(config)],
504
+ plugins: [VitePluginDevProxy(config)],
505
+ });
506
+ ```
507
+
508
+ ## ⚙️ 与其他工具对比
509
+
510
+ | 功能 | dev-proxy-plugin | vite-plugin-proxy | http-proxy-middleware |
511
+ | ------------- | ------------------ | ----------------- | --------------------- |
512
+ | 双框架支持 | ✅ Vite + Vue CLI | ❌ | ✅ |
513
+ | HTML 脚本注入 | ✅ | ❌ | ❌ |
514
+ | 脚本清除 | ✅ 4种类型 | ❌ | ❌ |
515
+ | Cookie 重写 | ✅ 自动 | ❌ | ⚠️ 手动 |
516
+ | 重定向处理 | ✅ 自动转换 | ⚠️ | ⚠️ |
517
+ | 压缩支持 | ✅ gzip/deflate/br | ❌ | ⚠️ |
518
+ | 灵活配置 | ✅ 4种类型 | ⚠️ 数组 | ⚠️ 对象 |
519
+ | TypeScript | ✅ 完整 | ⚠️ 部分 | ✅ |
520
+ | 文档 | ✅ 详细 | ⚠️ 简单 | ✅ |
521
+ | 代码量 | 📦 ~850 行 | - | - |
522
+
523
+ ## 💡 常见问题
524
+
525
+ ### 1. 为什么需要这个插件?
526
+
527
+ **场景**:你的项目依赖后端服务器渲染的 HTML,但你想在本地开发时使用 Vite/Vue CLI 的热更新功能。
528
+
529
+ **解决方案**:
530
+
531
+ - 代理远程服务器的 HTML
532
+ - 清除远程的脚本和样式
533
+ - 注入本地开发的脚本
534
+ - 处理 Cookie 和重定向问题
535
+
536
+ ### 2. `remotePrefixes` 和 `clearScriptCssPrefixes` 有什么区别?
537
+
538
+ - **`remotePrefixes`**:控制哪些**资源**从远程加载
539
+ - **`clearScriptCssPrefixes`**:控制哪些 HTML **标签**被清除
540
+
541
+ **示例**:
542
+
543
+ ```javascript
544
+ {
545
+ // /static/component 下的资源从远程加载
546
+ remotePrefixes: '/static/component',
547
+ // 但清除 HTML 中 /static 开头的 script/link 标签
548
+ clearScriptCssPrefixes: '/static',
549
+ }
550
+ ```
551
+
552
+ ### 3. 如何调试配置是否生效?
553
+
554
+ 开启 `debug: true`,查看控制台日志:
555
+
556
+ ```javascript
557
+ VitePluginDevProxy({
558
+ appHost: "example.com",
559
+ debug: true, // 开启调试
560
+ remotePrefixes: (url) => {
561
+ const isRemote = url.startsWith("/static");
562
+ console.log(`[自定义] ${url} -> ${isRemote ? "远程" : "本地"}`);
563
+ return isRemote;
564
+ },
204
565
  });
205
566
  ```
206
567
 
207
- ## Notes
568
+ ### 4. 支持哪些压缩格式?
208
569
 
209
- 1. `appHost` is a required parameter, not providing it will throw an error
210
- 2. The plugin will override `server.proxy` configuration in `vite.config.js`
211
- 3. Ensure the local development server port matches the port in redirect handling
212
- 4. Use `clearScriptCssPrefixes` to flexibly control which remote scripts and stylesheets to remove
213
- 5. Use `developmentAgentOccupancy` to specify a custom placeholder for script injection, or let the plugin automatically inject into `<div id="app">`
570
+ 支持 3 种常见的 HTTP 压缩格式:
214
571
 
215
- ## Requirements
572
+ - **gzip** - `Content-Encoding: gzip`
573
+ - **deflate** - `Content-Encoding: deflate`
574
+ - **brotli** - `Content-Encoding: br`
216
575
 
217
- - Vite 5.0+
218
- - Node.js 18+
576
+ ### 5. 如何与其他 Vite 插件配合使用?
577
+
578
+ 直接添加到 `plugins` 数组即可:
579
+
580
+ ```javascript
581
+ export default defineConfig({
582
+ plugins: [vue(), vueJsx(), VitePluginDevProxy({ appHost: "example.com" })],
583
+ });
584
+ ```
219
585
 
220
- ## License
586
+ ## 🤝 贡献
221
587
 
222
- MIT © [aiwa](https://cnlhb.github.io/blog/)
588
+ ## 📄 许可证
223
589
 
224
- ## Contributing
590
+ MIT License © 2024
225
591
 
226
- Contributions are welcome! Please feel free to submit a Pull Request.
592
+ ## 🔗 相关链接
227
593
 
228
- ## Issues
594
+ - [npm 包](https://www.npmjs.com/package/@xysfe/vite-plugin-dev-proxy)
229
595
 
230
- If you encounter any issues, please report them on [GitHub Issues](https://github.com/CNLHB/@xysfe/vite-plugin-dev-proxy/issues).
596
+ ---