From ada4446e5ce24e94f767fa384cd84695da48c17a Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sun, 12 Jun 2022 03:14:38 +0900 Subject: [PATCH 1/9] fix: default host to `localhost` instead of `127.0.0.1` --- .../vite/src/node/__tests__/utils.spec.ts | 25 ++++++++++++++-- packages/vite/src/node/logger.ts | 17 +++++++---- packages/vite/src/node/preview.ts | 6 ++-- packages/vite/src/node/server/index.ts | 8 ++--- packages/vite/src/node/utils.ts | 29 ++++++++++++------- 5 files changed, 61 insertions(+), 24 deletions(-) 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/logger.ts b/packages/vite/src/node/logger.ts index 1176a265a4fcbe..d69bace7d2369c 100644 --- a/packages/vite/src/node/logger.ts +++ b/packages/vite/src/node/logger.ts @@ -144,15 +144,15 @@ export function createLogger( return logger } -export function printCommonServerUrls( +export async function printCommonServerUrls( server: Server, options: CommonServerOptions, config: ResolvedConfig -): void { +): Promise { const address = server.address() const isAddressInfo = (x: any): x is AddressInfo => x?.address if (isAddressInfo(address)) { - const hostname = resolveHostname(options.host) + const hostname = await resolveHostname(options.host) const protocol = options.https ? 'https' : 'http' printServerUrls( hostname, @@ -164,6 +164,13 @@ export function printCommonServerUrls( } } +const loopbackHosts = new Set([ + 'localhost', + '127.0.0.1', + '::1', + '0000:0000:0000:0000:0000:0000:0000:0001' +]) + function printServerUrls( hostname: Hostname, protocol: string, @@ -173,7 +180,7 @@ function printServerUrls( ): void { const urls: Array<{ label: string; url: string }> = [] - if (hostname.host === '127.0.0.1') { + if (loopbackHosts.has(hostname.host)) { urls.push({ label: 'Local', url: colors.cyan( @@ -181,7 +188,7 @@ function printServerUrls( ) }) - 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`) diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index a8cb533e35ad19..1b36040e9ebaa8 100644 --- a/packages/vite/src/node/preview.ts +++ b/packages/vite/src/node/preview.ts @@ -112,7 +112,7 @@ export async function preview( postHooks.forEach((fn) => fn && fn()) const options = config.preview - const hostname = resolveHostname(options.host) + const hostname = await resolveHostname(options.host) const port = options.port ?? 4173 const protocol = options.https ? 'https' : 'http' const logger = config.logger @@ -139,8 +139,8 @@ export async function preview( return { config, httpServer, - printUrls() { - printCommonServerUrls(httpServer, config.preview, config) + async printUrls() { + await printCommonServerUrls(httpServer, config.preview, config) } } } diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 33565d7390d601..c9bcea2c6d3a47 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -222,7 +222,7 @@ export interface ViteDevServer { /** * Print server urls */ - printUrls(): void + printUrls(): Promise /** * Restart the server. * @@ -355,9 +355,9 @@ export async function createServer( closeHttpServer() ]) }, - printUrls() { + async printUrls() { if (httpServer) { - printCommonServerUrls(httpServer, config.server, config) + await printCommonServerUrls(httpServer, config.server, config) } else { throw new Error('cannot print server URLs in middleware mode.') } @@ -561,7 +561,7 @@ async function startServer( const options = server.config.server const port = inlinePort ?? options.port ?? 5173 - const hostname = resolveHostname(options.host) + const hostname = await resolveHostname(options.host) const protocol = options.https ? 'https' : 'http' const info = server.config.logger.info diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 4840cc413eb378..52ff74eb330dcb 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -6,6 +6,7 @@ import { promisify } from 'util' import { URL, URLSearchParams, pathToFileURL } from 'url' import { builtinModules, createRequire } from 'module' import { performance } from 'perf_hooks' +import dns from 'dns/promises' import resolve from 'resolve' import type { FSWatcher } from 'chokidar' import remapping from '@ampproject/remapping' @@ -726,13 +727,19 @@ export interface Hostname { name: string } -export function resolveHostname( +const wildcardHosts = new Set([ + '0.0.0.0', + '::', + '0000:0000:0000:0000:0000:0000:0000:0000' +]) + +export async function resolveHostname( optionsHost: string | boolean | undefined -): Hostname { +): Promise { 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) @@ -740,14 +747,16 @@ 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 + + // 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 { host, name } } From aa8d5ca1ce5b482ca601a7b4b6d3aa1dd57aaa5e Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sun, 12 Jun 2022 03:29:37 +0900 Subject: [PATCH 2/9] fix: move dns.lookup --- packages/vite/src/node/http.ts | 12 ++++++++++-- packages/vite/src/node/logger.ts | 6 +++--- packages/vite/src/node/preview.ts | 6 +++--- packages/vite/src/node/server/index.ts | 6 +++--- packages/vite/src/node/utils.ts | 12 ++---------- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index 2a1c7c920b8ea9..ba9e7631c6f282 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 dns from 'dns/promises' 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 d69bace7d2369c..c171dae63f84ca 100644 --- a/packages/vite/src/node/logger.ts +++ b/packages/vite/src/node/logger.ts @@ -144,15 +144,15 @@ export function createLogger( return logger } -export async function printCommonServerUrls( +export function printCommonServerUrls( server: Server, options: CommonServerOptions, config: ResolvedConfig -): Promise { +): void { const address = server.address() const isAddressInfo = (x: any): x is AddressInfo => x?.address if (isAddressInfo(address)) { - const hostname = await resolveHostname(options.host) + const hostname = resolveHostname(options.host) const protocol = options.https ? 'https' : 'http' printServerUrls( hostname, diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index 1b36040e9ebaa8..a8cb533e35ad19 100644 --- a/packages/vite/src/node/preview.ts +++ b/packages/vite/src/node/preview.ts @@ -112,7 +112,7 @@ export async function preview( postHooks.forEach((fn) => fn && fn()) const options = config.preview - const hostname = await resolveHostname(options.host) + const hostname = resolveHostname(options.host) const port = options.port ?? 4173 const protocol = options.https ? 'https' : 'http' const logger = config.logger @@ -139,8 +139,8 @@ export async function preview( return { config, httpServer, - async printUrls() { - await printCommonServerUrls(httpServer, config.preview, config) + printUrls() { + printCommonServerUrls(httpServer, config.preview, config) } } } diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index c9bcea2c6d3a47..ff14f16f91bd3a 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -222,7 +222,7 @@ export interface ViteDevServer { /** * Print server urls */ - printUrls(): Promise + printUrls(): void /** * Restart the server. * @@ -355,9 +355,9 @@ export async function createServer( closeHttpServer() ]) }, - async printUrls() { + printUrls() { if (httpServer) { - await printCommonServerUrls(httpServer, config.server, config) + printCommonServerUrls(httpServer, config.server, config) } else { throw new Error('cannot print server URLs in middleware mode.') } diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 52ff74eb330dcb..f962611a4ce200 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -6,7 +6,6 @@ import { promisify } from 'util' import { URL, URLSearchParams, pathToFileURL } from 'url' import { builtinModules, createRequire } from 'module' import { performance } from 'perf_hooks' -import dns from 'dns/promises' import resolve from 'resolve' import type { FSWatcher } from 'chokidar' import remapping from '@ampproject/remapping' @@ -733,9 +732,9 @@ const wildcardHosts = new Set([ '0000:0000:0000:0000:0000:0000:0000:0000' ]) -export async function resolveHostname( +export function resolveHostname( optionsHost: string | boolean | undefined -): Promise { +): Hostname { let host: string | undefined if (optionsHost === undefined || optionsHost === false) { // Use a secure default @@ -751,13 +750,6 @@ export async function resolveHostname( const name = host === undefined || wildcardHosts.has(host) ? 'localhost' : host - // 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 { host, name } } From 74e0279096494abebcf642580d65168dd362c307 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sun, 12 Jun 2022 03:34:12 +0900 Subject: [PATCH 3/9] fix: use `dns.promises` --- packages/vite/src/node/http.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index ba9e7631c6f282..c2757f36477600 100644 --- a/packages/vite/src/node/http.ts +++ b/packages/vite/src/node/http.ts @@ -5,7 +5,7 @@ import type { OutgoingHttpHeaders as HttpServerHeaders } from 'http' import type { ServerOptions as HttpsServerOptions } from 'https' -import dns from 'dns/promises' +import { promises as dns } from 'dns' import type { Connect } from 'types/connect' import { isObject } from './utils' import type { ProxyOptions } from './server/middlewares/proxy' From aed60eba64b299f9dc988c2546e305a0b1d997e7 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sun, 12 Jun 2022 03:44:22 +0900 Subject: [PATCH 4/9] fix: IPv6 printServerUrls --- packages/vite/src/node/logger.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/logger.ts b/packages/vite/src/node/logger.ts index c171dae63f84ca..d65f07aa5d0c9e 100644 --- a/packages/vite/src/node/logger.ts +++ b/packages/vite/src/node/logger.ts @@ -181,10 +181,18 @@ function printServerUrls( const urls: Array<{ label: string; url: string }> = [] if (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}` ) }) From 3b08484bae553fe4176bd91dee733a82ffa56093 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sun, 12 Jun 2022 03:48:29 +0900 Subject: [PATCH 5/9] docs: update for default host change --- docs/config/server-options.md | 2 +- docs/guide/migration.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) 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). From 3eb8a99cd1e1efc1974fc5da723d39ae46e658bc Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sun, 12 Jun 2022 04:12:17 +0900 Subject: [PATCH 6/9] refactor: remove unused await --- packages/vite/src/node/server/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index ff14f16f91bd3a..33565d7390d601 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -561,7 +561,7 @@ async function startServer( const options = server.config.server const port = inlinePort ?? options.port ?? 5173 - const hostname = await resolveHostname(options.host) + const hostname = resolveHostname(options.host) const protocol = options.https ? 'https' : 'http' const info = server.config.logger.info From dd7448b0893fb67d6a139b7c7e94a76b64830b02 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sun, 12 Jun 2022 04:26:37 +0900 Subject: [PATCH 7/9] test: fix flaky test --- playground/css/postcss-caching/css.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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') From 7b88dff62dccec22a6b6e228c404ca4e6b7f699e Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Mon, 13 Jun 2022 00:41:02 +0900 Subject: [PATCH 8/9] refactor: apply suggestion --- packages/vite/src/node/logger.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/logger.ts b/packages/vite/src/node/logger.ts index d65f07aa5d0c9e..c989449ebe1b48 100644 --- a/packages/vite/src/node/logger.ts +++ b/packages/vite/src/node/logger.ts @@ -164,7 +164,7 @@ export function printCommonServerUrls( } } -const loopbackHosts = new Set([ +const loopbackHosts = new Set([ 'localhost', '127.0.0.1', '::1', @@ -180,7 +180,7 @@ function printServerUrls( ): void { const urls: Array<{ label: string; url: string }> = [] - if (loopbackHosts.has(hostname.host)) { + if (hostname.host && loopbackHosts.has(hostname.host)) { let hostnameName = hostname.name if ( hostnameName === '::1' || From 67d22bd917c6ce38f9353e4d77d3a69079e1f096 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Mon, 13 Jun 2022 23:44:17 +0900 Subject: [PATCH 9/9] chore: add message for wildcard hosts --- packages/vite/src/node/constants.ts | 12 ++++++++++++ packages/vite/src/node/logger.ts | 29 +++++++++++++++++++---------- packages/vite/src/node/utils.ts | 9 ++------- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/packages/vite/src/node/constants.ts b/packages/vite/src/node/constants.ts index 4e5d3da96f50da..3846d87c419616 100644 --- a/packages/vite/src/node/constants.ts +++ b/packages/vite/src/node/constants.ts @@ -99,3 +99,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/logger.ts b/packages/vite/src/node/logger.ts index c989449ebe1b48..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' @@ -164,13 +165,6 @@ export function printCommonServerUrls( } } -const loopbackHosts = new Set([ - 'localhost', - '127.0.0.1', - '::1', - '0000:0000:0000:0000:0000:0000:0000:0001' -]) - function printServerUrls( hostname: Hostname, protocol: string, @@ -227,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 f962611a4ce200..9f8a2d0f508429 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -22,7 +22,8 @@ import { DEFAULT_EXTENSIONS, ENV_PUBLIC_PATH, FS_PREFIX, - VALID_ID_PREFIX + VALID_ID_PREFIX, + wildcardHosts } from './constants' import type { ResolvedConfig } from '.' @@ -726,12 +727,6 @@ export interface Hostname { name: string } -const wildcardHosts = new Set([ - '0.0.0.0', - '::', - '0000:0000:0000:0000:0000:0000:0000:0000' -]) - export function resolveHostname( optionsHost: string | boolean | undefined ): Hostname {