fix: allow using vite as a proxy for another vite server (#13218)

Co-authored-by: sapphi-red <green@sapphi.red>
This commit is contained in:
divdavem 2023-06-15 14:49:41 +02:00 committed by GitHub
parent eb751032d5
commit 711dd80761
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 108 additions and 6 deletions

View File

@ -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)

View File

@ -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)
})

View File

@ -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',
)
})

View File

@ -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<void> }> {
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()])
},
}
}

View File

@ -0,0 +1,2 @@
root app<br />
<iframe src="/anotherApp" style="border: 0"></iframe>

View File

@ -0,0 +1 @@
<span class="content">other app</span>

View File

@ -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"
}
}

View File

@ -0,0 +1,9 @@
import { defineConfig } from 'vite'
export default defineConfig({
base: '/anotherApp',
server: {
port: 9607,
strictPort: true,
},
})

View File

@ -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"
}
}

View File

@ -0,0 +1,13 @@
import { defineConfig } from 'vite'
export default defineConfig({
server: {
port: 9606,
proxy: {
'/anotherApp': {
target: 'http://localhost:9607',
ws: true,
},
},
},
})

View File

@ -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,

View File

@ -995,6 +995,10 @@ importers:
playground/preserve-symlinks/module-a: {}
playground/proxy-hmr: {}
playground/proxy-hmr/other-app: {}
playground/resolve:
dependencies:
'@babel/runtime':