From da883b17afd8fd71a3f57c84f838ff6033881e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=9D=B1=E6=BE=94?= Date: Sun, 16 Jan 2022 12:23:49 +0800 Subject: [PATCH 1/4] feat: Check port usage correctly --- packages/vite/src/node/__tests__/http.spec.ts | 44 ++++++++++++ packages/vite/src/node/http.ts | 72 +++++++++++++++---- 2 files changed, 102 insertions(+), 14 deletions(-) create mode 100644 packages/vite/src/node/__tests__/http.spec.ts diff --git a/packages/vite/src/node/__tests__/http.spec.ts b/packages/vite/src/node/__tests__/http.spec.ts new file mode 100644 index 00000000000000..8e3e6d6335d011 --- /dev/null +++ b/packages/vite/src/node/__tests__/http.spec.ts @@ -0,0 +1,44 @@ +import { httpServerStart } from '../http' +import { resolveConfig } from '..' + +describe('start preview server', () => { + test('[strictPort=false, host=127.0.0.1] should use another port when already start a server on localhost.', async () => { + const originalPort = 5000 + const server = require('http').createServer() + server.listen(originalPort, 'localhost') + + const testServer = require('http').createServer() + const config = await resolveConfig({}, 'serve', 'production') + const port = await httpServerStart(testServer, { + port: originalPort, + strictPort: false, + host: '127.0.0.1', + logger: config.logger + }) + + expect(port).not.toEqual(originalPort) + + server.close() + testServer.close() + }) + + test('[strictPort=true, host=127.0.0.1] should use another port when already start a server on localhost.', async () => { + const originalPort = 5000 + const server = require('http').createServer() + server.listen(originalPort, 'localhost') + + const config = await resolveConfig({}, 'serve', 'production') + const testServer = require('http').createServer() + expect( + httpServerStart(testServer, { + port: originalPort, + strictPort: true, + host: '127.0.0.1', + logger: config.logger + }) + ).rejects.toEqual(new Error(`Port ${originalPort} is already in use`)) + + server.close() + testServer.close() + }) +}) diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index becc2191efac7f..96ed55e758e662 100644 --- a/packages/vite/src/node/http.ts +++ b/packages/vite/src/node/http.ts @@ -183,6 +183,39 @@ async function getCertificate(cacheDir?: string) { } } +function checkPortOccupied( + port: number, + host?: string +): Promise<{ port: number; occupied: boolean }> { + return new Promise((resolve, reject) => { + const tempServer = require('http').createServer() + + const onError = (e: Error & { code?: string }) => { + if (e.code === 'EADDRINUSE') { + checkPortOccupied(++port, host) + .then((r) => { + resolve({ + port: r.port, + occupied: true + }) + }) + .catch(reject) + } else { + reject(e) + } + tempServer.removeListener('error', onError) + tempServer.close() + } + + tempServer.on('error', onError) + + tempServer.listen(port, host, () => { + tempServer.removeListener('error', onError) + tempServer.close(() => resolve({ port, occupied: false })) + }) + }) +} + export async function httpServerStart( httpServer: HttpServer, serverOptions: { @@ -192,28 +225,39 @@ export async function httpServerStart( logger: Logger } ): Promise { + const { strictPort, host, logger } = serverOptions + // Check the port usage of serverOptions.host + let checkInfo = await checkPortOccupied(serverOptions.port, host) + + if (host === '127.0.0.1') { + // Check the port usage of localhost + checkInfo = await checkPortOccupied(serverOptions.port, 'localhost') + } + return new Promise((resolve, reject) => { - let { port, strictPort, host, logger } = serverOptions + const { port, occupied } = checkInfo - const onError = (e: Error & { code?: string }) => { - if (e.code === 'EADDRINUSE') { - if (strictPort) { - httpServer.removeListener('error', onError) - reject(new Error(`Port ${port} is already in use`)) - } else { - logger.info(`Port ${port} is in use, trying another one...`) - httpServer.listen(++port, host) - } - } else { - httpServer.removeListener('error', onError) - reject(e) - } + if (occupied && strictPort) { + reject(new Error(`Port ${serverOptions.port} is already in use`)) + return + } + + const onError = (e: Error) => { + httpServer.removeListener('error', onError) + reject(e) } httpServer.on('error', onError) httpServer.listen(port, host, () => { httpServer.removeListener('error', onError) + + if (occupied) { + logger.info( + `Port ${serverOptions.port} is in use, trying another one...` + ) + } + resolve(port) }) }) From 1fb96794f3df2420bf1e429c088be73dc79af68f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=9D=B1=E6=BE=94?= Date: Sun, 16 Jan 2022 15:01:30 +0800 Subject: [PATCH 2/4] chore: Move test file --- .../preview/__tests__/preview.spec.ts} | 4 ++-- packages/playground/preview/package.json | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) rename packages/{vite/src/node/__tests__/http.spec.ts => playground/preview/__tests__/preview.spec.ts} (93%) create mode 100644 packages/playground/preview/package.json diff --git a/packages/vite/src/node/__tests__/http.spec.ts b/packages/playground/preview/__tests__/preview.spec.ts similarity index 93% rename from packages/vite/src/node/__tests__/http.spec.ts rename to packages/playground/preview/__tests__/preview.spec.ts index 8e3e6d6335d011..19564f25bc125d 100644 --- a/packages/vite/src/node/__tests__/http.spec.ts +++ b/packages/playground/preview/__tests__/preview.spec.ts @@ -1,5 +1,5 @@ -import { httpServerStart } from '../http' -import { resolveConfig } from '..' +import { httpServerStart } from 'vite/src/node/http' +import { resolveConfig } from 'vite/src/node' describe('start preview server', () => { test('[strictPort=false, host=127.0.0.1] should use another port when already start a server on localhost.', async () => { diff --git a/packages/playground/preview/package.json b/packages/playground/preview/package.json new file mode 100644 index 00000000000000..77b6cf4aa1212b --- /dev/null +++ b/packages/playground/preview/package.json @@ -0,0 +1,9 @@ +{ + "name": "preview", + "version": "0.0.0", + "scripts": { + "dev": "vite --force", + "build": "vite build", + "preview": "vite preview" + } +} From 8b2b8cd4f77af517e00878757fef25f8934dd69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=9D=B1=E6=BE=94?= Date: Mon, 17 Jan 2022 19:39:04 +0800 Subject: [PATCH 3/4] test: modified test file --- packages/playground/preview/__tests__/preview.spec.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/playground/preview/__tests__/preview.spec.ts b/packages/playground/preview/__tests__/preview.spec.ts index 19564f25bc125d..fea79e01b84058 100644 --- a/packages/playground/preview/__tests__/preview.spec.ts +++ b/packages/playground/preview/__tests__/preview.spec.ts @@ -1,13 +1,14 @@ import { httpServerStart } from 'vite/src/node/http' import { resolveConfig } from 'vite/src/node' +import { createServer } from 'http' describe('start preview server', () => { test('[strictPort=false, host=127.0.0.1] should use another port when already start a server on localhost.', async () => { const originalPort = 5000 - const server = require('http').createServer() + const server = createServer() server.listen(originalPort, 'localhost') - const testServer = require('http').createServer() + const testServer = createServer() const config = await resolveConfig({}, 'serve', 'production') const port = await httpServerStart(testServer, { port: originalPort, @@ -24,12 +25,12 @@ describe('start preview server', () => { test('[strictPort=true, host=127.0.0.1] should use another port when already start a server on localhost.', async () => { const originalPort = 5000 - const server = require('http').createServer() + const server = createServer() server.listen(originalPort, 'localhost') const config = await resolveConfig({}, 'serve', 'production') - const testServer = require('http').createServer() - expect( + const testServer = createServer() + await expect( httpServerStart(testServer, { port: originalPort, strictPort: true, From 2e143034ceebec26293878c32af752ccf8785fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=9D=B1=E6=BE=94?= Date: Mon, 17 Jan 2022 22:26:49 +0800 Subject: [PATCH 4/4] test: Add index.html --- packages/playground/preview/index.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 packages/playground/preview/index.html diff --git a/packages/playground/preview/index.html b/packages/playground/preview/index.html new file mode 100644 index 00000000000000..6fada566b4aa8d --- /dev/null +++ b/packages/playground/preview/index.html @@ -0,0 +1,12 @@ + + + + + + Preview + + +

Preview

+
+ +