From 88875622818f773f9b439751351046aab8643db5 Mon Sep 17 00:00:00 2001 From: David-Emmanuel DIVERNOIS Date: Tue, 16 May 2023 17:01:52 +0200 Subject: [PATCH 1/3] fix: allow using vite as a proxy for another vite server --- .../vite/src/node/server/middlewares/proxy.ts | 8 +++--- packages/vite/src/node/server/ws.ts | 11 +++++++- .../proxy-hmr/__tests__/proxy-hmr.spec.ts | 15 +++++++++++ playground/proxy-hmr/__tests__/serve.ts | 27 +++++++++++++++++++ playground/proxy-hmr/index.html | 2 ++ playground/proxy-hmr/other-app/index.html | 1 + playground/proxy-hmr/other-app/package.json | 11 ++++++++ playground/proxy-hmr/other-app/vite.config.js | 9 +++++++ playground/proxy-hmr/package.json | 11 ++++++++ playground/proxy-hmr/vite.config.js | 12 +++++++++ 10 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 playground/proxy-hmr/__tests__/proxy-hmr.spec.ts create mode 100644 playground/proxy-hmr/__tests__/serve.ts create mode 100644 playground/proxy-hmr/index.html create mode 100644 playground/proxy-hmr/other-app/index.html create mode 100644 playground/proxy-hmr/other-app/package.json create mode 100644 playground/proxy-hmr/other-app/vite.config.js create mode 100644 playground/proxy-hmr/package.json create mode 100644 playground/proxy-hmr/vite.config.js diff --git a/packages/vite/src/node/server/middlewares/proxy.ts b/packages/vite/src/node/server/middlewares/proxy.ts index 66f99f94f0609d..ae289a8f8e9776 100644 --- a/packages/vite/src/node/server/middlewares/proxy.ts +++ b/packages/vite/src/node/server/middlewares/proxy.ts @@ -4,7 +4,6 @@ import httpProxy from 'http-proxy' import type { Connect } from 'dep-types/connect' import type { HttpProxy } from 'dep-types/http-proxy' import colors from 'picocolors' -import { HMR_HEADER } from '../ws' import { createDebugger } from '../../utils' import type { CommonServerOptions, ResolvedConfig } from '../..' @@ -103,10 +102,9 @@ export function proxyMiddleware( if (doesProxyContextMatchUrl(context, url)) { const [proxy, opts] = proxies[context] if ( - (opts.ws || - opts.target?.toString().startsWith('ws:') || - opts.target?.toString().startsWith('wss:')) && - req.headers['sec-websocket-protocol'] !== HMR_HEADER + opts.ws || + opts.target?.toString().startsWith('ws:') || + opts.target?.toString().startsWith('wss:') ) { if (opts.rewrite) { req.url = opts.rewrite(url) diff --git a/packages/vite/src/node/server/ws.ts b/packages/vite/src/node/server/ws.ts index 61d989080e7573..e1278959fedb27 100644 --- a/packages/vite/src/node/server/ws.ts +++ b/packages/vite/src/node/server/ws.ts @@ -1,3 +1,4 @@ +import path from 'node:path' import type { Server } from 'node:http' import { STATUS_CODES, createServer as createHttpServer } from 'node:http' import type { ServerOptions as HttpsServerOptions } from 'node:https' @@ -101,9 +102,17 @@ export function createWebSocketServer( const host = (hmr && hmr.host) || undefined if (wsServer) { + let hmrBase = config.base + const hmrPath = hmr ? hmr.path : undefined + if (hmrPath) { + hmrBase = path.posix.join(hmrBase, hmrPath) + } wss = new WebSocketServerRaw({ noServer: true }) wsServer.on('upgrade', (req, socket, head) => { - if (req.headers['sec-websocket-protocol'] === HMR_HEADER) { + if ( + req.headers['sec-websocket-protocol'] === HMR_HEADER && + req.url === hmrBase + ) { wss.handleUpgrade(req, socket as Socket, head, (ws) => { wss.emit('connection', ws, req) }) diff --git a/playground/proxy-hmr/__tests__/proxy-hmr.spec.ts b/playground/proxy-hmr/__tests__/proxy-hmr.spec.ts new file mode 100644 index 00000000000000..85fcde963cfc83 --- /dev/null +++ b/playground/proxy-hmr/__tests__/proxy-hmr.spec.ts @@ -0,0 +1,15 @@ +import { test } from 'vitest' +import { editFile, page, untilUpdated, viteTestUrl } from '~utils' + +test('proxy-hmr', async () => { + await page.goto(viteTestUrl) + const otherAppTextLocator = page.frameLocator('iframe').locator('.content') + await untilUpdated(() => otherAppTextLocator.textContent(), 'other app') + editFile('other-app/index.html', (code) => + code.replace('app', 'modified app'), + ) + await untilUpdated( + () => otherAppTextLocator.textContent(), + 'other modified app', + ) +}) diff --git a/playground/proxy-hmr/__tests__/serve.ts b/playground/proxy-hmr/__tests__/serve.ts new file mode 100644 index 00000000000000..9cbeef96edcbb2 --- /dev/null +++ b/playground/proxy-hmr/__tests__/serve.ts @@ -0,0 +1,27 @@ +// this is automatically detected by playground/vitestSetup.ts and will replace +// the default e2e test serve behavior + +import path from 'node:path' +import { rootDir, setViteUrl } from '~utils' + +export async function serve(): Promise<{ close(): Promise }> { + const vite = await import('vite') + const rootServer = await vite.createServer({ + root: rootDir, + logLevel: 'silent', + }) + const otherServer = await vite.createServer({ + root: path.join(rootDir, 'other-app'), + logLevel: 'silent', + }) + + await Promise.all([rootServer.listen(), otherServer.listen()]) + const viteUrl = rootServer.resolvedUrls.local[0] + setViteUrl(viteUrl) + + return { + async close() { + await Promise.all([rootServer.close(), otherServer.close()]) + }, + } +} diff --git a/playground/proxy-hmr/index.html b/playground/proxy-hmr/index.html new file mode 100644 index 00000000000000..f14fde8e428635 --- /dev/null +++ b/playground/proxy-hmr/index.html @@ -0,0 +1,2 @@ +root app
+ diff --git a/playground/proxy-hmr/other-app/index.html b/playground/proxy-hmr/other-app/index.html new file mode 100644 index 00000000000000..18f42b0b93d11c --- /dev/null +++ b/playground/proxy-hmr/other-app/index.html @@ -0,0 +1 @@ +other app diff --git a/playground/proxy-hmr/other-app/package.json b/playground/proxy-hmr/other-app/package.json new file mode 100644 index 00000000000000..4457d4da6ae217 --- /dev/null +++ b/playground/proxy-hmr/other-app/package.json @@ -0,0 +1,11 @@ +{ + "name": "@vitejs/test-other-app", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + } +} diff --git a/playground/proxy-hmr/other-app/vite.config.js b/playground/proxy-hmr/other-app/vite.config.js new file mode 100644 index 00000000000000..f916721a090fc9 --- /dev/null +++ b/playground/proxy-hmr/other-app/vite.config.js @@ -0,0 +1,9 @@ +import { defineConfig } from 'vite' + +export default defineConfig({ + base: '/anotherApp', + server: { + port: 3001, + strictPort: true, + }, +}) diff --git a/playground/proxy-hmr/package.json b/playground/proxy-hmr/package.json new file mode 100644 index 00000000000000..3aff8b1c8936fd --- /dev/null +++ b/playground/proxy-hmr/package.json @@ -0,0 +1,11 @@ +{ + "name": "@vitejs/test-proxy-hmr", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + } +} diff --git a/playground/proxy-hmr/vite.config.js b/playground/proxy-hmr/vite.config.js new file mode 100644 index 00000000000000..29e69415d66bfa --- /dev/null +++ b/playground/proxy-hmr/vite.config.js @@ -0,0 +1,12 @@ +import { defineConfig } from 'vite' + +export default defineConfig({ + server: { + proxy: { + '/anotherApp': { + target: 'http://localhost:3001', + ws: true, + }, + }, + }, +}) From 00493ed0fba0e1577e9f9cb73956b2daf4481de6 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Thu, 15 Jun 2023 21:38:26 +0900 Subject: [PATCH 2/3] chore: update pnpm-lock --- pnpm-lock.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e0c939e96c82cf..60d050d34fc3f8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -980,6 +980,10 @@ importers: playground/preserve-symlinks/module-a: {} + playground/proxy-hmr: {} + + playground/proxy-hmr/other-app: {} + playground/resolve: dependencies: '@babel/runtime': From 299dd21db396a3e8e5f337a9cffe9082b7caf24f Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Thu, 15 Jun 2023 21:39:13 +0900 Subject: [PATCH 3/3] test: use dedicated port --- playground/proxy-hmr/other-app/vite.config.js | 2 +- playground/proxy-hmr/vite.config.js | 3 ++- playground/test-utils.ts | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/playground/proxy-hmr/other-app/vite.config.js b/playground/proxy-hmr/other-app/vite.config.js index f916721a090fc9..6e79541a31d806 100644 --- a/playground/proxy-hmr/other-app/vite.config.js +++ b/playground/proxy-hmr/other-app/vite.config.js @@ -3,7 +3,7 @@ import { defineConfig } from 'vite' export default defineConfig({ base: '/anotherApp', server: { - port: 3001, + port: 9607, strictPort: true, }, }) diff --git a/playground/proxy-hmr/vite.config.js b/playground/proxy-hmr/vite.config.js index 29e69415d66bfa..cd418eacdb5d35 100644 --- a/playground/proxy-hmr/vite.config.js +++ b/playground/proxy-hmr/vite.config.js @@ -2,9 +2,10 @@ import { defineConfig } from 'vite' export default defineConfig({ server: { + port: 9606, proxy: { '/anotherApp': { - target: 'http://localhost:3001', + target: 'http://localhost:9607', ws: true, }, }, diff --git a/playground/test-utils.ts b/playground/test-utils.ts index 26eaf5c1323982..f9db685abd8d95 100644 --- a/playground/test-utils.ts +++ b/playground/test-utils.ts @@ -30,6 +30,8 @@ export const ports = { 'ssr-noexternal': 9603, 'ssr-pug': 9604, 'ssr-webworker': 9605, + 'proxy-hmr': 9606, // not imported but used in `proxy-hmr/vite.config.js` + 'proxy-hmr/other-app': 9607, // not imported but used in `proxy-hmr/other-app/vite.config.js` 'css/postcss-caching': 5005, 'css/postcss-plugins-different-dir': 5006, 'css/dynamic-import': 5007,