Skip to content

Commit 49c0896

Browse files
authored
fix: default host to localhost instead of 127.0.0.1 (#8543)
1 parent 0e20949 commit 49c0896

File tree

8 files changed

+84
-21
lines changed

8 files changed

+84
-21
lines changed

docs/config/server-options.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## server.host
44

55
- **Type:** `string | boolean`
6-
- **Default:** `'127.0.0.1'`
6+
- **Default:** `'localhost'`
77

88
Specify which IP addresses the server should listen on.
99
Set this to `0.0.0.0` or `true` to listen on all addresses, including LAN and public addresses.

docs/guide/migration.md

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ A small fraction of users will now require using [@vitejs/plugin-legacy](https:/
3131

3232
Vite's default dev server port is now 5173. You can use [`server.port`](../config/server-options.md#server-port) to set it to 3000.
3333

34+
Vite's default dev server host is now `localhost`. You can use [`server.host`](../config/server-options.md#server-host) to set it to `127.0.0.1`.
35+
3436
Vite optimizes dependencies with esbuild to both convert CJS-only deps to ESM and to reduce the number of modules the browser needs to request. In v3, the default strategy to discover and batch dependencies has changed. Vite no longer pre-scans user code with esbuild to get an initial list of dependencies on cold start. Instead, it delays the first dependency optimization run until every imported user module on load is processed.
3537

3638
To get back the v2 strategy, you can use [`optimizeDeps.devScan`](../config/dep-optimization-options.md#optimizedepsdevscan).

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

+23-2
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ describe('injectQuery', () => {
4949
})
5050

5151
describe('resolveHostname', () => {
52-
test('defaults to 127.0.0.1', () => {
52+
test('defaults to localhost', () => {
5353
expect(resolveHostname(undefined)).toEqual({
54-
host: '127.0.0.1',
54+
host: 'localhost',
5555
name: 'localhost'
5656
})
5757
})
@@ -62,6 +62,27 @@ describe('resolveHostname', () => {
6262
name: 'localhost'
6363
})
6464
})
65+
66+
test('accepts 0.0.0.0', () => {
67+
expect(resolveHostname('0.0.0.0')).toEqual({
68+
host: '0.0.0.0',
69+
name: 'localhost'
70+
})
71+
})
72+
73+
test('accepts ::', () => {
74+
expect(resolveHostname('::')).toEqual({
75+
host: '::',
76+
name: 'localhost'
77+
})
78+
})
79+
80+
test('accepts 0000:0000:0000:0000:0000:0000:0000:0000', () => {
81+
expect(resolveHostname('0000:0000:0000:0000:0000:0000:0000:0000')).toEqual({
82+
host: '0000:0000:0000:0000:0000:0000:0000:0000',
83+
name: 'localhost'
84+
})
85+
})
6586
})
6687

6788
test('ts import of file with .js extension', () => {

packages/vite/src/node/constants.ts

+12
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,15 @@ export const DEFAULT_ASSETS_RE = new RegExp(
105105
)
106106

107107
export const DEP_VERSION_RE = /[\?&](v=[\w\.-]+)\b/
108+
109+
export const loopbackHosts = new Set([
110+
'localhost',
111+
'127.0.0.1',
112+
'::1',
113+
'0000:0000:0000:0000:0000:0000:0000:0001'
114+
])
115+
export const wildcardHosts = new Set([
116+
'0.0.0.0',
117+
'::',
118+
'0000:0000:0000:0000:0000:0000:0000:0000'
119+
])

packages/vite/src/node/http.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
OutgoingHttpHeaders as HttpServerHeaders
66
} from 'http'
77
import type { ServerOptions as HttpsServerOptions } from 'https'
8+
import { promises as dns } from 'dns'
89
import type { Connect } from 'types/connect'
910
import { isObject } from './utils'
1011
import type { ProxyOptions } from './server/middlewares/proxy'
@@ -184,9 +185,16 @@ export async function httpServerStart(
184185
logger: Logger
185186
}
186187
): Promise<number> {
187-
return new Promise((resolve, reject) => {
188-
let { port, strictPort, host, logger } = serverOptions
188+
let { port, strictPort, host, logger } = serverOptions
189+
190+
// This could be removed when Vite only supports Node 17+ because verbatim=true is default
191+
// https://github.com/nodejs/node/pull/39987
192+
if (host === 'localhost') {
193+
const addr = await dns.lookup('localhost', { verbatim: true })
194+
host = addr.address
195+
}
189196

197+
return new Promise((resolve, reject) => {
190198
const onError = (e: Error & { code?: string }) => {
191199
if (e.code === 'EADDRINUSE') {
192200
if (strictPort) {

packages/vite/src/node/logger.ts

+30-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { RollupError } from 'rollup'
88
import type { CommonServerOptions } from './http'
99
import type { Hostname } from './utils'
1010
import { resolveHostname } from './utils'
11+
import { loopbackHosts, wildcardHosts } from './constants'
1112
import type { ResolvedConfig } from '.'
1213

1314
export type LogType = 'error' | 'warn' | 'info'
@@ -173,15 +174,23 @@ function printServerUrls(
173174
): void {
174175
const urls: Array<{ label: string; url: string }> = []
175176

176-
if (hostname.host === '127.0.0.1') {
177+
if (hostname.host && loopbackHosts.has(hostname.host)) {
178+
let hostnameName = hostname.name
179+
if (
180+
hostnameName === '::1' ||
181+
hostnameName === '0000:0000:0000:0000:0000:0000:0000:0001'
182+
) {
183+
hostnameName = `[${hostnameName}]`
184+
}
185+
177186
urls.push({
178187
label: 'Local',
179188
url: colors.cyan(
180-
`${protocol}://${hostname.name}:${colors.bold(port)}${base}`
189+
`${protocol}://${hostnameName}:${colors.bold(port)}${base}`
181190
)
182191
})
183192

184-
if (hostname.name !== '127.0.0.1') {
193+
if (hostname.name === 'localhost') {
185194
urls.push({
186195
label: 'Network',
187196
url: colors.dim(`use ${colors.white(colors.bold('--host'))} to expose`)
@@ -212,11 +221,26 @@ function printServerUrls(
212221
(length, { label }) => Math.max(length, label.length),
213222
0
214223
)
215-
urls.forEach(({ label, url: text }) => {
224+
const print = (
225+
iconWithColor: string,
226+
label: string,
227+
messageWithColor: string
228+
) => {
216229
info(
217-
` ${colors.green('➜')} ${colors.bold(label)}: ${' '.repeat(
230+
` ${iconWithColor} ${colors.bold(label)}: ${' '.repeat(
218231
length - label.length
219-
)}${text}`
232+
)}${messageWithColor}`
220233
)
234+
}
235+
236+
urls.forEach(({ label, url: text }) => {
237+
print(colors.green('➜'), label, text)
221238
})
239+
if (!hostname.host || wildcardHosts.has(hostname.host)) {
240+
print(
241+
colors.bold(colors.blue('ⓘ')),
242+
'Note',
243+
colors.dim('You are using a wildcard host. Ports might be overriden.')
244+
)
245+
}
222246
}

packages/vite/src/node/utils.ts

+5-9
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import {
2323
DEFAULT_EXTENSIONS,
2424
ENV_PUBLIC_PATH,
2525
FS_PREFIX,
26-
VALID_ID_PREFIX
26+
VALID_ID_PREFIX,
27+
wildcardHosts
2728
} from './constants'
2829
import type { ResolvedConfig } from '.'
2930

@@ -747,22 +748,17 @@ export function resolveHostname(
747748
let host: string | undefined
748749
if (optionsHost === undefined || optionsHost === false) {
749750
// Use a secure default
750-
host = '127.0.0.1'
751+
host = 'localhost'
751752
} else if (optionsHost === true) {
752753
// If passed --host in the CLI without arguments
753754
host = undefined // undefined typically means 0.0.0.0 or :: (listen on all IPs)
754755
} else {
755756
host = optionsHost
756757
}
757758

758-
// Set host name to localhost when possible, unless the user explicitly asked for '127.0.0.1'
759+
// Set host name to localhost when possible
759760
const name =
760-
(optionsHost !== '127.0.0.1' && host === '127.0.0.1') ||
761-
host === '0.0.0.0' ||
762-
host === '::' ||
763-
host === undefined
764-
? 'localhost'
765-
: host
761+
host === undefined || wildcardHosts.has(host) ? 'localhost' : host
766762

767763
return { host, name }
768764
}

playground/css/postcss-caching/css.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ test('postcss config', async () => {
3636
blueApp = null
3737

3838
greenApp = await startServer(greenAppDir)
39-
await page.goto(`http://localhost:${port}`)
39+
await page.reload() // hmr reloads it automatically but reload here for consistency
4040
const greenA = await page.$('.postcss-a')
4141
expect(await getColor(greenA)).toBe('black')
4242
const greenB = await page.$('.postcss-b')

0 commit comments

Comments
 (0)