Skip to content

Commit

Permalink
fix: allow using vite as a proxy for another vite server (#13218)
Browse files Browse the repository at this point in the history
Co-authored-by: sapphi-red <[email protected]>
  • Loading branch information
divdavem and sapphi-red authored Jun 15, 2023
1 parent eb75103 commit 711dd80
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 6 deletions.
8 changes: 3 additions & 5 deletions packages/vite/src/node/server/middlewares/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 '../..'

Expand Down Expand Up @@ -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)
Expand Down
11 changes: 10 additions & 1 deletion packages/vite/src/node/server/ws.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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)
})
Expand Down
15 changes: 15 additions & 0 deletions playground/proxy-hmr/__tests__/proxy-hmr.spec.ts
Original file line number Diff line number Diff line change
@@ -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',
)
})
27 changes: 27 additions & 0 deletions playground/proxy-hmr/__tests__/serve.ts
Original file line number Diff line number Diff line change
@@ -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()])
},
}
}
2 changes: 2 additions & 0 deletions playground/proxy-hmr/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
root app<br />
<iframe src="/anotherApp" style="border: 0"></iframe>
1 change: 1 addition & 0 deletions playground/proxy-hmr/other-app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<span class="content">other app</span>
11 changes: 11 additions & 0 deletions playground/proxy-hmr/other-app/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
9 changes: 9 additions & 0 deletions playground/proxy-hmr/other-app/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'vite'

export default defineConfig({
base: '/anotherApp',
server: {
port: 9607,
strictPort: true,
},
})
11 changes: 11 additions & 0 deletions playground/proxy-hmr/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
13 changes: 13 additions & 0 deletions playground/proxy-hmr/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineConfig } from 'vite'

export default defineConfig({
server: {
port: 9606,
proxy: {
'/anotherApp': {
target: 'http://localhost:9607',
ws: true,
},
},
},
})
2 changes: 2 additions & 0 deletions playground/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 711dd80

Please sign in to comment.