Skip to content

Commit 45f6443

Browse files
authored
feat: resolve server URLs before calling other listeners (#19981)
1 parent c1279e7 commit 45f6443

File tree

5 files changed

+102
-16
lines changed

5 files changed

+102
-16
lines changed

packages/vite/src/node/__tests__/dev.spec.ts

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
import { describe, expect, test } from 'vitest'
2-
import { resolveConfig } from '..'
1+
import { afterEach, describe, expect, test } from 'vitest'
2+
import type { ResolvedServerUrls } from 'vite'
3+
import { createServer, resolveConfig } from '..'
4+
import type { ViteDevServer } from '..'
5+
import { promiseWithResolvers } from '../../shared/utils'
36

47
describe('resolveBuildEnvironmentOptions in dev', () => {
58
test('build.rollupOptions should not have input in lib', async () => {
@@ -17,3 +20,49 @@ describe('resolveBuildEnvironmentOptions in dev', () => {
1720
expect(config.build.rollupOptions).not.toHaveProperty('input')
1821
})
1922
})
23+
24+
describe('the dev server', () => {
25+
let server: ViteDevServer
26+
27+
afterEach(() => {
28+
server?.close()
29+
})
30+
31+
test('resolves the server URLs before the httpServer listening events are called', async () => {
32+
expect.assertions(1)
33+
34+
const options = {
35+
port: 5013, // make sure the port is unique
36+
}
37+
38+
const { promise, resolve } =
39+
promiseWithResolvers<ResolvedServerUrls | null>()
40+
server = await createServer({
41+
root: __dirname,
42+
logLevel: 'error',
43+
server: {
44+
strictPort: true,
45+
ws: false,
46+
...options,
47+
},
48+
plugins: [
49+
{
50+
name: 'test',
51+
configureServer(server) {
52+
server.httpServer?.on('listening', () => {
53+
resolve(server.resolvedUrls)
54+
})
55+
},
56+
},
57+
],
58+
})
59+
60+
await server.listen()
61+
const urls = await promise
62+
63+
expect(urls).toStrictEqual({
64+
local: ['http://localhost:5013/'],
65+
network: [],
66+
})
67+
})
68+
})

packages/vite/src/node/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,7 +1365,7 @@ export async function resolveConfig(
13651365
)
13661366
: ''
13671367

1368-
const server = resolveServerOptions(resolvedRoot, config.server, logger)
1368+
const server = await resolveServerOptions(resolvedRoot, config.server, logger)
13691369

13701370
const builder = resolveBuilderOptions(config.builder)
13711371

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { describe, expect, it, vi } from 'vitest'
2+
import { resolveServerOptions } from '../index'
3+
4+
describe('resolveServerOptions', () => {
5+
const root = '/test'
6+
const logger = {
7+
warn: vi.fn(),
8+
} as any
9+
10+
it('should use a default hostname when no host is provided', async () => {
11+
const resolvedOptions = await resolveServerOptions(root, {}, logger)
12+
13+
expect(resolvedOptions.hostname).toStrictEqual({
14+
host: 'localhost',
15+
name: 'localhost',
16+
})
17+
})
18+
19+
it('should resolve the hostname correctly', async () => {
20+
const options = {
21+
host: '127.0.0.1',
22+
}
23+
const resolvedOptions = await resolveServerOptions(root, options, logger)
24+
25+
expect(resolvedOptions.hostname).toStrictEqual({
26+
host: '127.0.0.1',
27+
name: '127.0.0.1',
28+
})
29+
})
30+
})

packages/vite/src/node/server/index.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
} from '../http'
2525
import type { InlineConfig, ResolvedConfig } from '../config'
2626
import { isResolvedConfig, resolveConfig } from '../config'
27+
import type { Hostname } from '../utils'
2728
import {
2829
diffDnsOrderChange,
2930
getServerUrlByHost,
@@ -206,6 +207,8 @@ export interface ResolvedServerOptions
206207
> {
207208
fs: Required<FileSystemServeOptions>
208209
middlewareMode: NonNullable<ServerOptions['middlewareMode']>
210+
/** @internal */
211+
hostname: Hostname
209212
sourcemapIgnoreList: Exclude<
210213
ServerOptions['sourcemapIgnoreList'],
211214
false | undefined
@@ -643,14 +646,18 @@ export async function _createServer(
643646
}
644647
},
645648
async listen(port?: number, isRestart?: boolean) {
649+
if (httpServer) {
650+
httpServer.prependListener('listening', () => {
651+
server.resolvedUrls = resolveServerUrls(
652+
httpServer,
653+
config.server,
654+
httpsOptions,
655+
config,
656+
)
657+
})
658+
}
646659
await startServer(server, port)
647660
if (httpServer) {
648-
server.resolvedUrls = await resolveServerUrls(
649-
httpServer,
650-
config.server,
651-
httpsOptions,
652-
config,
653-
)
654661
if (!isRestart && config.server.open) server.openBrowser()
655662
}
656663
return server
@@ -998,7 +1005,6 @@ async function startServer(
9981005
}
9991006

10001007
const options = server.config.server
1001-
const hostname = await resolveHostname(options.host)
10021008
const configPort = inlinePort ?? options.port
10031009
// When using non strict port for the dev server, the running port can be different from the config one.
10041010
// When restarting, the original port may be available but to avoid a switch of URL for the running
@@ -1012,7 +1018,7 @@ async function startServer(
10121018
const serverPort = await httpServerStart(httpServer, {
10131019
port,
10141020
strictPort: options.strictPort,
1015-
host: hostname.host,
1021+
host: options.hostname.host,
10161022
logger: server.config.logger,
10171023
})
10181024
server._currentServerPort = serverPort
@@ -1090,11 +1096,11 @@ export const serverConfigDefaults = Object.freeze({
10901096
// hotUpdateEnvironments
10911097
} satisfies ServerOptions)
10921098

1093-
export function resolveServerOptions(
1099+
export async function resolveServerOptions(
10941100
root: string,
10951101
raw: ServerOptions | undefined,
10961102
logger: Logger,
1097-
): ResolvedServerOptions {
1103+
): Promise<ResolvedServerOptions> {
10981104
const _server = mergeWithDefaults(
10991105
{
11001106
...serverConfigDefaults,
@@ -1106,6 +1112,7 @@ export function resolveServerOptions(
11061112

11071113
const server: ResolvedServerOptions = {
11081114
..._server,
1115+
hostname: await resolveHostname(_server.host),
11091116
fs: {
11101117
..._server.fs,
11111118
// run searchForWorkspaceRoot only if needed

packages/vite/src/node/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -961,12 +961,12 @@ export async function resolveHostname(
961961
return { host, name }
962962
}
963963

964-
export async function resolveServerUrls(
964+
export function resolveServerUrls(
965965
server: Server,
966966
options: CommonServerOptions,
967967
httpsOptions: HttpsServerOptions | undefined,
968968
config: ResolvedConfig,
969-
): Promise<ResolvedServerUrls> {
969+
): ResolvedServerUrls {
970970
const address = server.address()
971971

972972
const isAddressInfo = (x: any): x is AddressInfo => x?.address
@@ -976,7 +976,7 @@ export async function resolveServerUrls(
976976

977977
const local: string[] = []
978978
const network: string[] = []
979-
const hostname = await resolveHostname(options.host)
979+
const hostname = config.server.hostname
980980
const protocol = options.https ? 'https' : 'http'
981981
const port = address.port
982982
const base =

0 commit comments

Comments
 (0)