From 49c089662916bb2c0ae2aae649c7c8b714509922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Tue, 14 Jun 2022 14:53:40 +0900 Subject: [PATCH] fix: default host to `localhost` instead of `127.0.0.1` (#8543) --- docs/config/server-options.md | 2 +- docs/guide/migration.md | 2 ++ .../vite/src/node/__tests__/utils.spec.ts | 25 +++++++++++-- packages/vite/src/node/constants.ts | 12 +++++++ packages/vite/src/node/http.ts | 12 +++++-- packages/vite/src/node/logger.ts | 36 +++++++++++++++---- packages/vite/src/node/utils.ts | 14 +++----- playground/css/postcss-caching/css.spec.ts | 2 +- 8 files changed, 84 insertions(+), 21 deletions(-) diff --git a/docs/config/server-options.md b/docs/config/server-options.md index cf59ab27644656..a3f82aa0f12b79 100644 --- a/docs/config/server-options.md +++ b/docs/config/server-options.md @@ -3,7 +3,7 @@ ## server.host - **Type:** `string | boolean` -- **Default:** `'127.0.0.1'` +- **Default:** `'localhost'` Specify which IP addresses the server should listen on. Set this to `0.0.0.0` or `true` to listen on all addresses, including LAN and public addresses. diff --git a/docs/guide/migration.md b/docs/guide/migration.md index 78b738afb82ddf..c3e7be3a8a2c27 100644 --- a/docs/guide/migration.md +++ b/docs/guide/migration.md @@ -31,6 +31,8 @@ A small fraction of users will now require using [@vitejs/plugin-legacy](https:/ 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. +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`. + 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. To get back the v2 strategy, you can use [`optimizeDeps.devScan`](../config/dep-optimization-options.md#optimizedepsdevscan). diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts index c8a824bbb3d28f..5a6ea4d55de30c 100644 --- a/packages/vite/src/node/__tests__/utils.spec.ts +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -49,9 +49,9 @@ describe('injectQuery', () => { }) describe('resolveHostname', () => { - test('defaults to 127.0.0.1', () => { + test('defaults to localhost', () => { expect(resolveHostname(undefined)).toEqual({ - host: '127.0.0.1', + host: 'localhost', name: 'localhost' }) }) @@ -62,6 +62,27 @@ describe('resolveHostname', () => { name: 'localhost' }) }) + + test('accepts 0.0.0.0', () => { + expect(resolveHostname('0.0.0.0')).toEqual({ + host: '0.0.0.0', + name: 'localhost' + }) + }) + + test('accepts ::', () => { + expect(resolveHostname('::')).toEqual({ + host: '::', + name: 'localhost' + }) + }) + + test('accepts 0000:0000:0000:0000:0000:0000:0000:0000', () => { + expect(resolveHostname('0000:0000:0000:0000:0000:0000:0000:0000')).toEqual({ + host: '0000:0000:0000:0000:0000:0000:0000:0000', + name: 'localhost' + }) + }) }) test('ts import of file with .js extension', () => { diff --git a/packages/vite/src/node/constants.ts b/packages/vite/src/node/constants.ts index acd067908a598c..3b4d496e30bd3c 100644 --- a/packages/vite/src/node/constants.ts +++ b/packages/vite/src/node/constants.ts @@ -105,3 +105,15 @@ export const DEFAULT_ASSETS_RE = new RegExp( ) export const DEP_VERSION_RE = /[\?&](v=[\w\.-]+)\b/ + +export const loopbackHosts = new Set([ + 'localhost', + '127.0.0.1', + '::1', + '0000:0000:0000:0000:0000:0000:0000:0001' +]) +export const wildcardHosts = new Set([ + '0.0.0.0', + '::', + '0000:0000:0000:0000:0000:0000:0000:0000' +]) diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index 2a1c7c920b8ea9..c2757f36477600 100644 --- a/packages/vite/src/node/http.ts +++ b/packages/vite/src/node/http.ts @@ -5,6 +5,7 @@ import type { OutgoingHttpHeaders as HttpServerHeaders } from 'http' import type { ServerOptions as HttpsServerOptions } from 'https' +import { promises as dns } from 'dns' import type { Connect } from 'types/connect' import { isObject } from './utils' import type { ProxyOptions } from './server/middlewares/proxy' @@ -184,9 +185,16 @@ export async function httpServerStart( logger: Logger } ): Promise { - return new Promise((resolve, reject) => { - let { port, strictPort, host, logger } = serverOptions + let { port, strictPort, host, logger } = serverOptions + + // This could be removed when Vite only supports Node 17+ because verbatim=true is default + // https://github.com/nodejs/node/pull/39987 + if (host === 'localhost') { + const addr = await dns.lookup('localhost', { verbatim: true }) + host = addr.address + } + return new Promise((resolve, reject) => { const onError = (e: Error & { code?: string }) => { if (e.code === 'EADDRINUSE') { if (strictPort) { diff --git a/packages/vite/src/node/logger.ts b/packages/vite/src/node/logger.ts index 1176a265a4fcbe..d3ed4ce896d6fb 100644 --- a/packages/vite/src/node/logger.ts +++ b/packages/vite/src/node/logger.ts @@ -8,6 +8,7 @@ import type { RollupError } from 'rollup' import type { CommonServerOptions } from './http' import type { Hostname } from './utils' import { resolveHostname } from './utils' +import { loopbackHosts, wildcardHosts } from './constants' import type { ResolvedConfig } from '.' export type LogType = 'error' | 'warn' | 'info' @@ -173,15 +174,23 @@ function printServerUrls( ): void { const urls: Array<{ label: string; url: string }> = [] - if (hostname.host === '127.0.0.1') { + if (hostname.host && loopbackHosts.has(hostname.host)) { + let hostnameName = hostname.name + if ( + hostnameName === '::1' || + hostnameName === '0000:0000:0000:0000:0000:0000:0000:0001' + ) { + hostnameName = `[${hostnameName}]` + } + urls.push({ label: 'Local', url: colors.cyan( - `${protocol}://${hostname.name}:${colors.bold(port)}${base}` + `${protocol}://${hostnameName}:${colors.bold(port)}${base}` ) }) - if (hostname.name !== '127.0.0.1') { + if (hostname.name === 'localhost') { urls.push({ label: 'Network', url: colors.dim(`use ${colors.white(colors.bold('--host'))} to expose`) @@ -212,11 +221,26 @@ function printServerUrls( (length, { label }) => Math.max(length, label.length), 0 ) - urls.forEach(({ label, url: text }) => { + const print = ( + iconWithColor: string, + label: string, + messageWithColor: string + ) => { info( - ` ${colors.green('➜')} ${colors.bold(label)}: ${' '.repeat( + ` ${iconWithColor} ${colors.bold(label)}: ${' '.repeat( length - label.length - )}${text}` + )}${messageWithColor}` ) + } + + urls.forEach(({ label, url: text }) => { + print(colors.green('➜'), label, text) }) + if (!hostname.host || wildcardHosts.has(hostname.host)) { + print( + colors.bold(colors.blue('ⓘ')), + 'Note', + colors.dim('You are using a wildcard host. Ports might be overriden.') + ) + } } diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index fff0d714770c8d..e36e33c3cb7225 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -23,7 +23,8 @@ import { DEFAULT_EXTENSIONS, ENV_PUBLIC_PATH, FS_PREFIX, - VALID_ID_PREFIX + VALID_ID_PREFIX, + wildcardHosts } from './constants' import type { ResolvedConfig } from '.' @@ -747,7 +748,7 @@ export function resolveHostname( let host: string | undefined if (optionsHost === undefined || optionsHost === false) { // Use a secure default - host = '127.0.0.1' + host = 'localhost' } else if (optionsHost === true) { // If passed --host in the CLI without arguments host = undefined // undefined typically means 0.0.0.0 or :: (listen on all IPs) @@ -755,14 +756,9 @@ export function resolveHostname( host = optionsHost } - // Set host name to localhost when possible, unless the user explicitly asked for '127.0.0.1' + // Set host name to localhost when possible const name = - (optionsHost !== '127.0.0.1' && host === '127.0.0.1') || - host === '0.0.0.0' || - host === '::' || - host === undefined - ? 'localhost' - : host + host === undefined || wildcardHosts.has(host) ? 'localhost' : host return { host, name } } diff --git a/playground/css/postcss-caching/css.spec.ts b/playground/css/postcss-caching/css.spec.ts index bbffdb618280e4..45e8aadaa5489c 100644 --- a/playground/css/postcss-caching/css.spec.ts +++ b/playground/css/postcss-caching/css.spec.ts @@ -36,7 +36,7 @@ test('postcss config', async () => { blueApp = null greenApp = await startServer(greenAppDir) - await page.goto(`http://localhost:${port}`) + await page.reload() // hmr reloads it automatically but reload here for consistency const greenA = await page.$('.postcss-a') expect(await getColor(greenA)).toBe('black') const greenB = await page.$('.postcss-b')