Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.