@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/dist/index.mjs CHANGED
@@ -2,205 +2,305 @@ import zlib from 'zlib';
2
2
  import { resolve } from 'path';
3
3
  import fs from 'fs';
4
4
 
5
- function createProxyConfig(options) {
6
- const {
5
+ const SCRIPT_LINK_REGEX = /<(?:script[^>]*>.*?<\/script>|link[^>]*>)/g;
6
+ const ASSET_REGEX = /\.(js|mjs|ts|tsx|jsx|css|scss|sass|less|vue|json|woff2?|ttf|eot|ico|png|jpe?g|gif|svg|webp)(\?.*)?$/i;
7
+ const STATIC_PATH_REGEX = /^\/(static|assets|public|images|css|js)\//i;
8
+ const BYPASS_REGEX = /\.(vue|js|mjs|ts|tsx|jsx|css|scss|sass|less|json|png|jpe?g|gif|svg|webp|ico|woff2?|ttf|eot)$/i;
9
+ const REDIRECT_STATUS_MIN = 300;
10
+ const REDIRECT_STATUS_MAX = 400;
11
+ const DEFAULT_APP_DIV_REGEX = /<div[^>]*id=["']app["'][^>]*><\/div>/g;
12
+ const HTTPS_TO_HTTP_REGEX = /https:\/\/(localhost|127\.0\.0\.1|192\.168\.\d{1,3}\.\d{1,3}|10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(?:1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3})(:\d+)?/gi;
13
+ function createLogger(debug) {
14
+ return {
15
+ log: debug ? console.log.bind(console) : () => {
16
+ },
17
+ logError: debug ? console.error.bind(console) : () => {
18
+ }
19
+ };
20
+ }
21
+ function normalizePath(path) {
22
+ return path.endsWith("/") ? path.slice(0, -1) : path;
23
+ }
24
+ function generateEntryScript(entry, staticPrefix) {
25
+ if (Array.isArray(entry)) {
26
+ return entry.map(
27
+ (e) => `<script crossorigin type="module" src="${staticPrefix + e}"><\/script>`
28
+ ).join("\n");
29
+ }
30
+ return `<script crossorigin type="module" src="${staticPrefix + entry}"><\/script>`;
31
+ }
32
+ function rewriteCookies(headers, log2) {
33
+ const setCookie = headers["set-cookie"];
34
+ if (setCookie) {
35
+ headers["set-cookie"] = setCookie.map((cookie) => {
36
+ const rewrittenCookie = cookie.replace(/;\s*secure\s*(;|$)/gi, "$1").replace(/;\s*domain\s*=[^;]+(;|$)/gi, "$1").replace(/;\s*samesite\s*=[^;]+(;|$)/gi, "$1").replace(/;+/g, ";").replace(/;\s*$/g, "");
37
+ log2("[rewrittenCookie]", rewrittenCookie);
38
+ return rewrittenCookie;
39
+ });
40
+ }
41
+ return headers;
42
+ }
43
+ function decompressBuffer(buffer, encoding) {
44
+ if (encoding === "gzip") {
45
+ return zlib.gunzipSync(buffer);
46
+ } else if (encoding === "deflate") {
47
+ return zlib.inflateSync(buffer);
48
+ } else if (encoding === "br") {
49
+ return zlib.brotliDecompressSync(buffer);
50
+ }
51
+ return buffer;
52
+ }
53
+ function shouldClearScriptCss(match, clearRule) {
54
+ const srcMatch = match.match(/src="([^"]+)"/i);
55
+ const hrefMatch = match.match(/href="([^"]+)"/i);
56
+ const srcOrHref = srcMatch ? srcMatch[1] : hrefMatch ? hrefMatch[1] : null;
57
+ if (clearRule === "") {
58
+ return false;
59
+ }
60
+ if (typeof clearRule === "string") {
61
+ return srcOrHref?.startsWith(clearRule) ?? false;
62
+ }
63
+ if (Array.isArray(clearRule)) {
64
+ return clearRule.some((prefix) => srcOrHref?.startsWith(prefix));
65
+ }
66
+ if (clearRule instanceof RegExp) {
67
+ return clearRule.test(match);
68
+ }
69
+ if (typeof clearRule === "function") {
70
+ return clearRule(match);
71
+ }
72
+ return false;
73
+ }
74
+ function injectEntryScript(html, fullEntry, developmentAgentOccupancy) {
75
+ if (developmentAgentOccupancy) {
76
+ return html.replace(developmentAgentOccupancy, fullEntry);
77
+ }
78
+ return html.replace(DEFAULT_APP_DIV_REGEX, (match) => `${match}${fullEntry}`);
79
+ }
80
+ function clearScriptCssTags(html, clearRule, log2) {
81
+ return html.replace(SCRIPT_LINK_REGEX, (match) => {
82
+ const isClear = shouldClearScriptCss(match, clearRule);
83
+ if (isClear) {
84
+ log2?.(`[clearScriptCssTags]: ${match}`);
85
+ }
86
+ return isClear ? "" : match;
87
+ });
88
+ }
89
+ function isRedirectResponse(proxyRes) {
90
+ return proxyRes.statusCode >= REDIRECT_STATUS_MIN && proxyRes.statusCode < REDIRECT_STATUS_MAX && !!proxyRes.headers.location;
91
+ }
92
+ function shouldProcessAsHtml(contentType, acceptHeader, requestUrl, isRedirect) {
93
+ const isNavigationRequest = acceptHeader.includes("text/html");
94
+ const isAssetRequest = ASSET_REGEX.test(requestUrl);
95
+ const isStaticPath = STATIC_PATH_REGEX.test(requestUrl);
96
+ return contentType.includes("text/html") && isNavigationRequest && !isAssetRequest && !isStaticPath && !isRedirect;
97
+ }
98
+ function matchesRemoteResource(url, remoteRule) {
99
+ if (typeof remoteRule === "string") {
100
+ return url.startsWith(remoteRule);
101
+ }
102
+ if (Array.isArray(remoteRule)) {
103
+ return remoteRule.some((prefix) => url.startsWith(prefix));
104
+ }
105
+ if (remoteRule instanceof RegExp) {
106
+ return remoteRule.test(url);
107
+ }
108
+ if (typeof remoteRule === "function") {
109
+ return remoteRule(url);
110
+ }
111
+ return false;
112
+ }
113
+ function shouldUseLocal(url, normalizedStaticPrefix, remotePrefixes) {
114
+ const pathname = url.split("?")[0];
115
+ const isLocalResource = normalizedStaticPrefix && url.startsWith(normalizedStaticPrefix) || url.startsWith("/@") || url.startsWith("/src") || url.startsWith("/node_modules") || url.includes(".hot-update.") || url.startsWith("/sockjs-node") || // Vue CLI/Webpack 热更新 WebSocket (3.x)
116
+ url.startsWith("/ws") || // Vue CLI/Webpack 热更新 WebSocket (4.x+/Vite)
117
+ url === "/" || BYPASS_REGEX.test(pathname);
118
+ const isRemoteResource = matchesRemoteResource(url, remotePrefixes);
119
+ return isLocalResource && !isRemoteResource;
120
+ }
121
+ function handleRedirect(proxyRes, req, res, appHost, log2, startTime) {
122
+ const redirectUrl = proxyRes.headers.location;
123
+ const host = req.headers.host;
124
+ const regex = new RegExp(appHost, "gi");
125
+ let location = redirectUrl.replace(regex, host || "");
126
+ location = location.replace(HTTPS_TO_HTTP_REGEX, "http://$1$2");
127
+ const headers = rewriteCookies({ ...proxyRes.headers }, log2);
128
+ headers.location = location;
129
+ res.writeHead(proxyRes.statusCode, headers);
130
+ res.end();
131
+ log2(
132
+ `Redirect handled: ${redirectUrl} -> ${location} (${Date.now() - startTime}ms)`
133
+ );
134
+ }
135
+ function handleLibModeHtml(localIndexHtml, res, log2, logError, startTime) {
136
+ try {
137
+ const indexHtml = fs.readFileSync(
138
+ resolve(__dirname, localIndexHtml),
139
+ "utf-8"
140
+ );
141
+ res.writeHead(200, {
142
+ "Content-Type": "text/html; charset=utf-8"
143
+ });
144
+ res.end(indexHtml);
145
+ log2(`Local HTML served: ${localIndexHtml} (${Date.now() - startTime}ms)`);
146
+ } catch (err) {
147
+ logError("Failed to read local HTML:", err);
148
+ res.writeHead(500);
149
+ res.end("Failed to read local HTML");
150
+ }
151
+ }
152
+ function handleHtmlResponse(proxyRes, req, res, context) {
153
+ const encoding = proxyRes.headers["content-encoding"];
154
+ const requestUrl = req.url || "";
155
+ const chunks = [];
156
+ proxyRes.on("data", (chunk) => {
157
+ if (chunk) {
158
+ chunks.push(chunk);
159
+ }
160
+ });
161
+ proxyRes.on("end", () => {
162
+ try {
163
+ const buffer = Buffer.concat(chunks);
164
+ const decompressed = decompressBuffer(buffer, encoding);
165
+ let html = decompressed.toString("utf-8");
166
+ html = injectEntryScript(
167
+ html,
168
+ context.fullEntry,
169
+ context.developmentAgentOccupancy
170
+ );
171
+ html = clearScriptCssTags(
172
+ html,
173
+ context.clearScriptCssPrefixes,
174
+ context.log
175
+ );
176
+ const headers = rewriteCookies({ ...proxyRes.headers }, context.log);
177
+ headers["content-type"] = "text/html; charset=utf-8";
178
+ delete headers["content-encoding"];
179
+ delete headers["content-length"];
180
+ res.writeHead(200, headers);
181
+ res.end(html);
182
+ context.log(
183
+ `[HTML processed]: ${requestUrl} (${Date.now() - context.startTime}ms)`
184
+ );
185
+ } catch (err) {
186
+ context.logError("Decompress error:", err);
187
+ context.logError("Request URL:", requestUrl);
188
+ context.logError("Response headers:", proxyRes.headers);
189
+ res.writeHead(500);
190
+ res.end("Decompress error");
191
+ }
192
+ });
193
+ }
194
+ function validateOptions(options, pluginName) {
195
+ const { appHost } = options;
196
+ if (!appHost) {
197
+ throw new Error(`${pluginName}: appHost is required`);
198
+ }
199
+ }
200
+ function processOptions(options, isVite) {
201
+ let {
7
202
  https = true,
8
203
  appHost = "",
9
- isLib = false,
10
- localIndexHtml = "index.html",
11
- staticPrefix = "",
12
- bypassPrefixes = ["/static"],
13
- // scriptCssPrefix = "",
204
+ localIndexHtml = "",
205
+ staticPrefix = "/dev/static",
206
+ remotePrefixes = ["/static/component"],
14
207
  developmentAgentOccupancy = "",
15
208
  clearScriptCssPrefixes = "",
16
- entry = "/src/main.js",
209
+ entry = isVite ? "/src/main.js" : ["/js/chunk-vendors.js", "/js/app.js"],
17
210
  debug = false
18
211
  } = options;
19
- if (!appHost) {
20
- throw new Error("vite-plugin-dev-proxy: appHost is required");
21
- }
22
- if (!Array.isArray(bypassPrefixes)) {
23
- throw new Error("vite-plugin-dev-proxy: bypassPrefixes must be an array");
24
- }
25
- const log = debug ? console.log : () => {
26
- };
27
- const logError = debug ? console.error : () => {
212
+ appHost = normalizePath(appHost);
213
+ const normalizedStaticPrefix = normalizePath(staticPrefix);
214
+ const fullEntry = generateEntryScript(entry, normalizedStaticPrefix);
215
+ const { log: log2, logError } = createLogger(debug);
216
+ return {
217
+ https,
218
+ appHost,
219
+ localIndexHtml,
220
+ normalizedStaticPrefix,
221
+ remotePrefixes,
222
+ developmentAgentOccupancy,
223
+ clearScriptCssPrefixes,
224
+ fullEntry,
225
+ log: log2,
226
+ logError
28
227
  };
29
- const normalizedStaticPrefix = staticPrefix.endsWith("/") ? staticPrefix.slice(0, -1) : staticPrefix;
228
+ }
229
+
230
+ function createProxyConfig(options) {
231
+ validateOptions(options, "vite-plugin-dev-proxy");
232
+ const {
233
+ https,
234
+ appHost,
235
+ localIndexHtml,
236
+ normalizedStaticPrefix,
237
+ remotePrefixes,
238
+ developmentAgentOccupancy,
239
+ clearScriptCssPrefixes,
240
+ fullEntry,
241
+ log,
242
+ logError
243
+ } = processOptions(options, true);
30
244
  log("vite-plugin-dev-proxy: staticPrefix", normalizedStaticPrefix);
31
- const fullEntry = normalizedStaticPrefix + entry;
32
- const scriptLinkRegex = /<(?:script[^>]*>.*?<\/script>|link[^>]*>)/g;
33
- const assetRegex = /\.(js|mjs|ts|tsx|jsx|css|scss|sass|less|vue|json|woff2?|ttf|eot|ico|png|jpe?g|gif|svg|webp)(\?.*)?$/i;
34
- const staticPathRegex = /^\/(static|assets|public|images|css|js)\//i;
35
- const bypassRegex = /\.(vue|js|mjs|ts|tsx|jsx|css|scss|sass|less|json|png|jpe?g|gif|svg|webp|ico|woff2?|ttf|eot)$/i;
245
+ const protocol = https ? "https://" : "http://";
36
246
  return {
37
247
  "/": {
38
- target: `${https ? "https" : "http"}://${appHost}`,
248
+ target: `${protocol}${appHost}`,
39
249
  changeOrigin: true,
40
250
  secure: false,
41
251
  cookieDomainRewrite: { "*": "localhost" },
42
252
  selfHandleResponse: true,
43
- configure: (proxy, options2) => {
44
- const rewriteCookies = (headers) => {
45
- const setCookie = headers["set-cookie"];
46
- if (setCookie) {
47
- headers["set-cookie"] = setCookie.map((cookie) => {
48
- let rewrittenCookie = cookie.replace(/;\s*secure\s*(;|$)/gi, "$1").replace(/;\s*domain\s*=[^;]+(;|$)/gi, "$1").replace(/;\s*samesite\s*=[^;]+(;|$)/gi, "$1").replace(/;+/g, ";").replace(/;\s*$/g, "");
49
- log("vite-plugin-dev-proxy: rewrittenCookie", rewrittenCookie);
50
- return rewrittenCookie;
51
- });
52
- }
53
- return headers;
54
- };
253
+ configure: (proxy, _options) => {
55
254
  proxy.on(
56
255
  "proxyRes",
57
256
  (proxyRes, req, res) => {
58
257
  const startTime = Date.now();
59
258
  const contentType = proxyRes.headers["content-type"] || "";
60
- const redirectUrl = proxyRes.headers.location;
61
259
  const requestUrl = req.url || "";
62
260
  const acceptHeader = req.headers.accept || "";
63
- const isRedirect = proxyRes.statusCode >= 300 && proxyRes.statusCode < 400 && redirectUrl;
261
+ const isRedirect = isRedirectResponse(proxyRes);
64
262
  if (isRedirect) {
65
- const host = req.headers.host;
66
- const regex = new RegExp(appHost, "gi");
67
- let location = redirectUrl.replace(regex, host || "");
68
- location = location.replace(
69
- /https:\/\/(localhost|127\.0\.0\.1)(:\d+)?/gi,
70
- "http://$1$2"
71
- );
72
- const headers2 = rewriteCookies({ ...proxyRes.headers });
73
- headers2.location = location;
74
- res.writeHead(proxyRes.statusCode, headers2);
75
- res.end();
76
- log(
77
- `Redirect handled: ${redirectUrl} -> ${location} (${Date.now() - startTime}ms)`
78
- );
263
+ handleRedirect(proxyRes, req, res, appHost, log, startTime);
79
264
  return;
80
265
  }
81
- const isNavigationRequest = acceptHeader.includes("text/html");
82
- const isAssetRequest = assetRegex.test(requestUrl);
83
- const isStaticPath = staticPathRegex.test(requestUrl);
84
- const shouldProcessHtml = contentType.includes("text/html") && isNavigationRequest && !isAssetRequest && !isStaticPath && !isRedirect;
266
+ const shouldProcessHtml = shouldProcessAsHtml(
267
+ contentType,
268
+ acceptHeader,
269
+ requestUrl,
270
+ isRedirect
271
+ );
85
272
  if (shouldProcessHtml) {
86
- if (isLib) {
87
- try {
88
- const indexHtml = fs.readFileSync(
89
- resolve(__dirname, localIndexHtml),
90
- "utf-8"
91
- );
92
- res.writeHead(200, {
93
- "Content-Type": "text/html; charset=utf-8"
94
- });
95
- res.end(indexHtml);
96
- log(
97
- `Local HTML served: ${localIndexHtml}\uFF09 (${Date.now() - startTime}ms)`
98
- );
99
- } catch (err) {
100
- logError("Failed to read local HTML:", err);
101
- res.writeHead(500);
102
- res.end("Failed to read local HTML");
103
- }
273
+ if (localIndexHtml) {
274
+ handleLibModeHtml(
275
+ localIndexHtml,
276
+ res,
277
+ log,
278
+ logError,
279
+ startTime
280
+ );
104
281
  return;
105
282
  }
106
- const encoding = proxyRes.headers["content-encoding"];
107
- const chunks = [];
108
- proxyRes.on(
109
- "data",
110
- (chunk) => {
111
- if (chunk) {
112
- chunks.push(chunk);
113
- }
114
- }
115
- );
116
- proxyRes.on("end", () => {
117
- try {
118
- let buffer = Buffer.concat(chunks);
119
- const decompress = () => {
120
- if (encoding === "gzip") {
121
- return zlib.gunzipSync(buffer);
122
- } else if (encoding === "deflate") {
123
- return zlib.inflateSync(buffer);
124
- } else if (encoding === "br") {
125
- return zlib.brotliDecompressSync(buffer);
126
- }
127
- return buffer;
128
- };
129
- const decompressed = decompress();
130
- let html = decompressed.toString("utf-8");
131
- if (developmentAgentOccupancy) {
132
- html = html.replace(
133
- developmentAgentOccupancy,
134
- `<script crossorigin type="module" src="${fullEntry}"><\/script>`
135
- );
136
- } else {
137
- html = html.replace(
138
- /<div[^>]*id=["']app["'][^>]*><\/div>/g,
139
- (match) => `${match}<script crossorigin type="module" src="${fullEntry}"><\/script>`
140
- );
141
- }
142
- clearScriptCssPrefixes;
143
- html = html.replace(scriptLinkRegex, (match) => {
144
- const srcMatch = match.match(/src="([^"]+)"/i);
145
- const hrefMatch = match.match(/href="([^"]+)"/i);
146
- const srcOrHref = srcMatch ? srcMatch[1] : hrefMatch ? hrefMatch[1] : null;
147
- if (typeof clearScriptCssPrefixes === "string") {
148
- if (srcOrHref?.startsWith(clearScriptCssPrefixes)) {
149
- return "";
150
- }
151
- }
152
- if (Array.isArray(clearScriptCssPrefixes)) {
153
- if (clearScriptCssPrefixes.some(
154
- (prefix) => srcOrHref?.startsWith(prefix)
155
- )) {
156
- return "";
157
- }
158
- }
159
- if (clearScriptCssPrefixes instanceof RegExp) {
160
- return clearScriptCssPrefixes.test(match) ? "" : match;
161
- }
162
- if (typeof clearScriptCssPrefixes === "function") {
163
- return clearScriptCssPrefixes(match) ? "" : match;
164
- }
165
- return match;
166
- });
167
- if (html.indexOf(fullEntry) === -1) {
168
- html = html.replace(
169
- /<!--\sS 公共组件 提示信息\s-->/g,
170
- `<script crossorigin type="module" src="${fullEntry}"><\/script>`
171
- );
172
- }
173
- const headers2 = rewriteCookies({ ...proxyRes.headers });
174
- headers2["content-type"] = "text/html; charset=utf-8";
175
- delete headers2["content-encoding"];
176
- delete headers2["content-length"];
177
- res.writeHead(200, headers2);
178
- res.end(html);
179
- log(
180
- `HTML processed: ${requestUrl} (${Date.now() - startTime}ms)`
181
- );
182
- } catch (err) {
183
- logError("Decompress error:", err);
184
- logError("Request URL:", requestUrl);
185
- logError("Response headers:", proxyRes.headers);
186
- res.writeHead(500);
187
- res.end("Decompress error");
188
- }
283
+ handleHtmlResponse(proxyRes, req, res, {
284
+ fullEntry,
285
+ developmentAgentOccupancy,
286
+ clearScriptCssPrefixes,
287
+ log,
288
+ logError,
289
+ startTime
189
290
  });
190
291
  return;
191
292
  }
192
- const headers = rewriteCookies({ ...proxyRes.headers });
293
+ const headers = rewriteCookies({ ...proxyRes.headers }, log);
193
294
  res.writeHead(proxyRes.statusCode, headers);
194
295
  proxyRes.pipe(res);
195
- log(`Proxy request: ${requestUrl} (${Date.now() - startTime}ms)`);
296
+ log(`[Proxy request] ${requestUrl} (${Date.now() - startTime}ms)`);
196
297
  }
197
298
  );
198
299
  },
199
300
  bypass: (req) => {
200
301
  const url = req.url || "";
201
- const pathname = url.split("?")[0];
202
- if ((normalizedStaticPrefix && url.startsWith(`${normalizedStaticPrefix}`) || url.startsWith("/@") || url.startsWith("/src") || url.startsWith("/node_modules") || url.includes(".hot-update.") || url === "/" || bypassRegex.test(pathname)) && !bypassPrefixes.some((prefix) => url.startsWith(prefix))) {
203
- log(`Bypass proxy: ${url}`);
302
+ if (shouldUseLocal(url, normalizedStaticPrefix, remotePrefixes)) {
303
+ log(`shouldUseLocal: ${url}`);
204
304
  return url;
205
305
  }
206
306
  }
@@ -229,4 +329,126 @@ function viteDevProxy(options = {}) {
229
329
  };
230
330
  }
231
331
 
232
- export { viteDevProxy as default };
332
+ function createVueCliProxyConfig(options) {
333
+ validateOptions(options, "vue-cli-plugin-dev-proxy");
334
+ const {
335
+ https,
336
+ appHost,
337
+ localIndexHtml,
338
+ normalizedStaticPrefix,
339
+ remotePrefixes,
340
+ developmentAgentOccupancy,
341
+ clearScriptCssPrefixes,
342
+ fullEntry,
343
+ log,
344
+ logError
345
+ } = processOptions(options);
346
+ log("vue-cli-plugin-dev-proxy: staticPrefix", normalizedStaticPrefix);
347
+ const protocol = https ? "https://" : "http://";
348
+ return {
349
+ "/": {
350
+ target: `${protocol}${appHost}`,
351
+ changeOrigin: true,
352
+ secure: false,
353
+ ws: false,
354
+ //5.x 版本需要设置,否则会报错 Invalid frame header,4.x 版本不需要设置
355
+ cookieDomainRewrite: { "*": "localhost" },
356
+ selfHandleResponse: true,
357
+ onProxyReq: (proxyReq, req, res) => {
358
+ const upgradeHeader = req.headers.upgrade;
359
+ const isWebSocket = upgradeHeader && upgradeHeader.toLowerCase() === "websocket";
360
+ if (isWebSocket) {
361
+ log(
362
+ `[WebSocket] ${req.method} ${req.url} -> ${protocol}${proxyReq.getHeader("host")}${proxyReq.path}`
363
+ );
364
+ } else {
365
+ log(
366
+ `[proxyReq] ${req.method} ${req.url} -> ${protocol}${proxyReq.getHeader("host")}${proxyReq.path}`
367
+ );
368
+ }
369
+ },
370
+ onError: (err, req, res) => {
371
+ const upgradeHeader = req.headers.upgrade;
372
+ const isWebSocket = upgradeHeader && upgradeHeader.toLowerCase() === "websocket";
373
+ if (isWebSocket) {
374
+ logError(`[WebSocket Error] ${req.url}:`, err.message);
375
+ } else {
376
+ logError(`[proxyError] ${req.url}:`, err.message);
377
+ }
378
+ if (!res.headersSent && !isWebSocket) {
379
+ res.writeHead(500, { "Content-Type": "text/plain" });
380
+ res.end("Proxy Error: " + err.message);
381
+ }
382
+ },
383
+ onProxyRes: (proxyRes, req, res) => {
384
+ const startTime = Date.now();
385
+ const contentType = proxyRes.headers["content-type"] || "";
386
+ const requestUrl = req.url || "";
387
+ const acceptHeader = req.headers.accept || "";
388
+ log(
389
+ `[proxyRes] ${requestUrl} - Status: ${proxyRes.statusCode}, ContentType: ${contentType}`
390
+ );
391
+ const isRedirect = isRedirectResponse(proxyRes);
392
+ if (isRedirect) {
393
+ handleRedirect(proxyRes, req, res, appHost, log, startTime);
394
+ return;
395
+ }
396
+ const shouldProcessHtml = shouldProcessAsHtml(
397
+ contentType,
398
+ acceptHeader,
399
+ requestUrl,
400
+ isRedirect
401
+ );
402
+ log(
403
+ `[shouldProcessHtml] ${shouldProcessHtml}, requestUrl: ${requestUrl}`
404
+ );
405
+ if (shouldProcessHtml) {
406
+ if (localIndexHtml) {
407
+ handleLibModeHtml(localIndexHtml, res, log, logError, startTime);
408
+ return;
409
+ }
410
+ handleHtmlResponse(proxyRes, req, res, {
411
+ fullEntry,
412
+ developmentAgentOccupancy,
413
+ clearScriptCssPrefixes,
414
+ log,
415
+ logError,
416
+ startTime
417
+ });
418
+ return;
419
+ }
420
+ const headers = rewriteCookies({ ...proxyRes.headers }, log);
421
+ res.writeHead(proxyRes.statusCode, headers);
422
+ proxyRes.pipe(res);
423
+ log(`[Proxy request]: ${requestUrl} (${Date.now() - startTime}ms)`);
424
+ },
425
+ bypass: (req) => {
426
+ const url = req.url || "";
427
+ if (shouldUseLocal(url, normalizedStaticPrefix, remotePrefixes)) {
428
+ log(`[shouldUseLocal] ${url}`);
429
+ return url;
430
+ }
431
+ log(`[Proxy] ${url}`);
432
+ return null;
433
+ }
434
+ }
435
+ };
436
+ }
437
+ function vueCliDevProxy(options = {}) {
438
+ if (process.env.NODE_ENV !== "development") {
439
+ return {};
440
+ }
441
+ const proxyConfig = createVueCliProxyConfig(options);
442
+ return {
443
+ devServer: {
444
+ proxy: proxyConfig
445
+ }
446
+ };
447
+ }
448
+
449
+ const index = {
450
+ VitePluginDevProxy: viteDevProxy,
451
+ VueCliPluginDevProxy: vueCliDevProxy
452
+ };
453
+
454
+ export { viteDevProxy as VitePluginDevProxy, vueCliDevProxy as VueCliPluginDevProxy, createVueCliProxyConfig, index as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xysfe/vite-plugin-dev-proxy",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "A Vite plugin for development environment proxy that automatically proxies remote server requests and handles HTML responses",
5
5
  "files": [
6
6
  "dist"
@@ -51,6 +51,5 @@
51
51
  "typescript": "^5.3.3",
52
52
  "unbuild": "^2.0.0",
53
53
  "vite": "^5.0.12"
54
- },
55
- "packageManager": "pnpm"
54
+ }
56
55
  }