0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-06 22:10:10 -05:00

Refactor server url logs (#4509)

* Refactor server url logs

* Fix test

* Fix build
This commit is contained in:
Bjorn Lu 2022-09-22 01:25:16 +08:00 committed by GitHub
parent b0cc939961
commit a0619f0869
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 113 additions and 53 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Refactor server url logs

View file

@ -60,19 +60,17 @@ export default async function dev(
runHookServerSetup({ config: settings.config, server: viteServer, logging: options.logging }); runHookServerSetup({ config: settings.config, server: viteServer, logging: options.logging });
await viteServer.listen(port); await viteServer.listen(port);
const devServerAddressInfo = viteServer.httpServer!.address() as AddressInfo;
const site = settings.config.site const site = settings.config.site
? new URL(settings.config.base, settings.config.site) ? new URL(settings.config.base, settings.config.site)
: undefined; : undefined;
info( info(
options.logging, options.logging,
null, null,
msg.devStart({ msg.serverStart({
startupTime: performance.now() - devStart, startupTime: performance.now() - devStart,
config: settings.config, resolvedUrls: viteServer.resolvedUrls || { local: [], network: [] },
devServerAddressInfo, host: settings.config.server.host,
site, site,
https: !!viteConfig.server?.https,
isRestart, isRestart,
}) })
); );
@ -85,6 +83,7 @@ export default async function dev(
warn(options.logging, null, msg.fsStrictWarning()); warn(options.logging, null, msg.fsStrictWarning());
} }
const devServerAddressInfo = viteServer.httpServer!.address() as AddressInfo;
await runHookServerStart({ await runHookServerStart({
config: settings.config, config: settings.config,
address: devServerAddressInfo, address: devServerAddressInfo,

View file

@ -16,9 +16,10 @@ import {
} from 'kleur/colors'; } from 'kleur/colors';
import type { AddressInfo } from 'net'; import type { AddressInfo } from 'net';
import os from 'os'; import os from 'os';
import { ResolvedServerUrls } from 'vite';
import { ZodError } from 'zod'; import { ZodError } from 'zod';
import type { AstroConfig } from '../@types/astro';
import { ErrorWithMetadata } from './errors.js'; import { ErrorWithMetadata } from './errors.js';
import { removeTrailingForwardSlash } from './path.js';
import { emoji, getLocalAddress, padMultilineString } from './util.js'; import { emoji, getLocalAddress, padMultilineString } from './util.js';
const PREFIX_PADDING = 6; const PREFIX_PADDING = 6;
@ -51,19 +52,17 @@ export function hmr({ file, style = false }: { file: string; style?: boolean }):
return `${green('update'.padStart(PREFIX_PADDING))} ${file}${style ? ` ${dim('style')}` : ''}`; return `${green('update'.padStart(PREFIX_PADDING))} ${file}${style ? ` ${dim('style')}` : ''}`;
} }
/** Display dev server host and startup time */ /** Display server host and startup time */
export function devStart({ export function serverStart({
startupTime, startupTime,
devServerAddressInfo, resolvedUrls,
config, host,
https,
site, site,
isRestart = false, isRestart = false,
}: { }: {
startupTime: number; startupTime: number;
devServerAddressInfo: AddressInfo; resolvedUrls: ResolvedServerUrls;
config: AstroConfig; host: string | boolean;
https: boolean;
site: URL | undefined; site: URL | undefined;
isRestart?: boolean; isRestart?: boolean;
}): string { }): string {
@ -72,19 +71,61 @@ export function devStart({
const rootPath = site ? site.pathname : '/'; const rootPath = site ? site.pathname : '/';
const localPrefix = `${dim('┃')} Local `; const localPrefix = `${dim('┃')} Local `;
const networkPrefix = `${dim('┃')} Network `; const networkPrefix = `${dim('┃')} Network `;
const emptyPrefix = ' '.repeat(11);
const { address: networkAddress, port } = devServerAddressInfo; const localUrlMessages = resolvedUrls.local.map((url, i) => {
const localAddress = getLocalAddress(networkAddress, config.server.host); return `${i === 0 ? localPrefix : emptyPrefix}${bold(
const networkLogging = getNetworkLogging(config.server.host); cyan(removeTrailingForwardSlash(url) + rootPath)
const toDisplayUrl = (hostname: string) => )}`;
`${https ? 'https' : 'http'}://${hostname}:${port}${rootPath}`; });
const networkUrlMessages = resolvedUrls.network.map((url, i) => {
return `${i === 0 ? networkPrefix : emptyPrefix}${bold(
cyan(removeTrailingForwardSlash(url) + rootPath)
)}`;
});
let local = `${localPrefix}${bold(cyan(toDisplayUrl(localAddress)))}`; if (networkUrlMessages.length === 0) {
let network = null; const networkLogging = getNetworkLogging(host);
if (networkLogging === 'host-to-expose') {
networkUrlMessages.push(`${networkPrefix}${dim('use --host to expose')}`);
} else if (networkLogging === 'visible') {
networkUrlMessages.push(`${networkPrefix}${dim('unable to find network to expose')}`);
}
}
if (networkLogging === 'host-to-expose') { const messages = [
network = `${networkPrefix}${dim('use --host to expose')}`; `${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim(
} else if (networkLogging === 'visible') { `${isRestart ? 're' : ''}started in ${Math.round(startupTime)}ms`
)}`,
'',
...localUrlMessages,
...networkUrlMessages,
'',
];
return messages
.filter((msg) => typeof msg === 'string')
.map((msg) => ` ${msg}`)
.join('\n');
}
export function resolveServerUrls({
address,
host,
https,
}: {
address: AddressInfo;
host: string | boolean;
https: boolean;
}): ResolvedServerUrls {
const { address: networkAddress, port } = address;
const localAddress = getLocalAddress(networkAddress, host);
const networkLogging = getNetworkLogging(host);
const toDisplayUrl = (hostname: string) => `${https ? 'https' : 'http'}://${hostname}:${port}`;
let local = toDisplayUrl(localAddress);
let network: string | null = null;
if (networkLogging === 'visible') {
const nodeVersion = Number(process.version.substring(1, process.version.indexOf('.', 5))); const nodeVersion = Number(process.version.substring(1, process.version.indexOf('.', 5)));
const ipv4Networks = Object.values(os.networkInterfaces()) const ipv4Networks = Object.values(os.networkInterfaces())
.flatMap((networkInterface) => networkInterface ?? []) .flatMap((networkInterface) => networkInterface ?? [])
@ -96,29 +137,17 @@ export function devStart({
for (let { address } of ipv4Networks) { for (let { address } of ipv4Networks) {
if (address.includes('127.0.0.1')) { if (address.includes('127.0.0.1')) {
const displayAddress = address.replace('127.0.0.1', localAddress); const displayAddress = address.replace('127.0.0.1', localAddress);
local = `${localPrefix}${bold(cyan(toDisplayUrl(displayAddress)))}`; local = toDisplayUrl(displayAddress);
} else { } else {
network = `${networkPrefix}${bold(cyan(toDisplayUrl(address)))}`; network = toDisplayUrl(address);
} }
} }
if (!network) {
network = `${networkPrefix}${dim('unable to find network to expose')}`;
}
} }
const messages = [ return {
`${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim( local: [local],
`${isRestart ? 're' : ''}started in ${Math.round(startupTime)}ms` network: network ? [network] : [],
)}`, };
'',
local,
network,
'',
];
return messages
.filter((msg) => typeof msg === 'string')
.map((msg) => ` ${msg}`)
.join('\n');
} }
export function telemetryNotice() { export function telemetryNotice() {

View file

@ -113,15 +113,18 @@ export default async function preview(
const listen = () => { const listen = () => {
httpServer = server.listen(port, host, async () => { httpServer = server.listen(port, host, async () => {
if (!showedListenMsg) { if (!showedListenMsg) {
const devServerAddressInfo = server.address() as AddressInfo; const resolvedUrls = msg.resolveServerUrls({
address: server.address() as AddressInfo,
host: settings.config.server.host,
https: false,
});
info( info(
logging, logging,
null, null,
msg.devStart({ msg.serverStart({
startupTime: performance.now() - timerStart, startupTime: performance.now() - timerStart,
config: settings.config, resolvedUrls,
devServerAddressInfo, host: settings.config.server.host,
https: false,
site: baseURL, site: baseURL,
}) })
); );

View file

@ -83,10 +83,17 @@ describe('astro cli', () => {
const localURL = new URL(local); const localURL = new URL(local);
const networkURL = new URL(network); const networkURL = new URL(network);
expect(localURL.hostname).to.be.equal( if (cmd === 'dev') {
flagValue ?? 'localhost', expect(localURL.hostname).to.be.oneOf(
`Expected local URL to be on localhost` ['localhost', '127.0.0.1'],
); `Expected local URL to be on localhost`
);
} else {
expect(localURL.hostname).to.be.equal(
flagValue ?? 'localhost',
`Expected local URL to be on localhost`
);
}
// Note: our tests run in parallel so this could be 3000+! // Note: our tests run in parallel so this could be 3000+!
expect(Number.parseInt(localURL.port)).to.be.greaterThanOrEqual( expect(Number.parseInt(localURL.port)).to.be.greaterThanOrEqual(
3000, 3000,
@ -112,7 +119,17 @@ describe('astro cli', () => {
expect(network).to.not.be.undefined; expect(network).to.not.be.undefined;
const localURL = new URL(local); const localURL = new URL(local);
expect(localURL.hostname).to.be.equal('localhost', `Expected local URL to be on localhost`); if (cmd === 'dev') {
expect(localURL.hostname).to.be.oneOf(
['localhost', '127.0.0.1'],
`Expected local URL to be on localhost`
);
} else {
expect(localURL.hostname).to.be.equal(
'localhost',
`Expected local URL to be on localhost`
);
}
expect(() => new URL(networkURL)).to.throw(); expect(() => new URL(networkURL)).to.throw();
}); });
}); });
@ -129,7 +146,14 @@ describe('astro cli', () => {
expect(network).to.be.undefined; expect(network).to.be.undefined;
const localURL = new URL(local); const localURL = new URL(local);
expect(localURL.hostname).to.be.equal(flagValue, `Expected local URL to be on localhost`); if (cmd === 'dev') {
expect(localURL.hostname).to.be.oneOf(
['localhost', '127.0.0.1'],
`Expected local URL to be on localhost`
);
} else {
expect(localURL.hostname).to.be.equal(flagValue, `Expected local URL to be on localhost`);
}
}); });
}); });
}); });