From b16cb787fd16ebaaf860d8bb183789caf01c0fb7 Mon Sep 17 00:00:00 2001 From: Jerry_wu <409187100@qq.com> Date: Fri, 11 Aug 2023 02:22:50 +0800 Subject: [PATCH] Support `--host` for Node adapter preview (#6928) * supporting a network address access a website when an user set host = true in Node environment * fix bug * sumbit test code * optimism * delect white space * test * fix test * fix test error * test * test * test * fix test error * Optimizing code based on the comments * optimize test * fix: rebase issues * chore: format * chore: add changeset * chore: format * chore: format * chore: lint --------- Co-authored-by: wuls Co-authored-by: Nate Moore --- .changeset/popular-spoons-behave.md | 5 +++ .../node/src/get-network-address.ts | 44 +++++++++++++++++++ packages/integrations/node/src/preview.ts | 12 ++++- packages/integrations/node/src/standalone.ts | 12 ++++- 4 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 .changeset/popular-spoons-behave.md create mode 100644 packages/integrations/node/src/get-network-address.ts diff --git a/.changeset/popular-spoons-behave.md b/.changeset/popular-spoons-behave.md new file mode 100644 index 000000000000..021705f41641 --- /dev/null +++ b/.changeset/popular-spoons-behave.md @@ -0,0 +1,5 @@ +--- +'@astrojs/node': patch +--- + +Support the `--host` flag when running the standalone server (also works for `astro preview --host`) diff --git a/packages/integrations/node/src/get-network-address.ts b/packages/integrations/node/src/get-network-address.ts new file mode 100644 index 000000000000..7d9f89a28b7f --- /dev/null +++ b/packages/integrations/node/src/get-network-address.ts @@ -0,0 +1,44 @@ +import os from 'os' +interface NetworkAddressOpt { + local: string[] + network: string[] +} + +const wildcardHosts = new Set([ + '0.0.0.0', + '::', + '0000:0000:0000:0000:0000:0000:0000:0000', +]) +type Protocol = 'http' | 'https' + +// this code from vite https://github.com/vitejs/vite/blob/d09bbd093a4b893e78f0bbff5b17c7cf7821f403/packages/vite/src/node/utils.ts#L892-L914 +export function getNetworkAddress(protocol: Protocol = 'http', hostname: string | undefined, port: number, base?: string) { + const NetworkAddress: NetworkAddressOpt = { + local: [], + network: [] + } + Object.values(os.networkInterfaces()) + .flatMap((nInterface) => nInterface ?? []) + .filter( + (detail) => + detail && + detail.address && + (detail.family === 'IPv4' || + // @ts-expect-error Node 18.0 - 18.3 returns number + detail.family === 4), + ) + .forEach((detail) => { + let host = detail.address.replace('127.0.0.1', hostname === undefined || wildcardHosts.has(hostname) ? 'localhost' : hostname) + // ipv6 host + if (host.includes(':')) { + host = `[${host}]` + } + const url = `${protocol}://${host}:${port}${base ? base : ''}` + if (detail.address.includes('127.0.0.1')) { + NetworkAddress.local.push(url) + } else { + NetworkAddress.network.push(url) + } + }) + return NetworkAddress +} diff --git a/packages/integrations/node/src/preview.ts b/packages/integrations/node/src/preview.ts index 92f9b86baa55..fdf2a5cbbde7 100644 --- a/packages/integrations/node/src/preview.ts +++ b/packages/integrations/node/src/preview.ts @@ -2,6 +2,7 @@ import type { CreatePreviewServer } from 'astro'; import type http from 'node:http'; import { fileURLToPath } from 'node:url'; import { createServer } from './http-server.js'; +import { getNetworkAddress } from './get-network-address.js' import type { createExports } from './server'; const preview: CreatePreviewServer = async function ({ @@ -67,9 +68,16 @@ const preview: CreatePreviewServer = async function ({ }, handler ); + const address = getNetworkAddress('http', host, port) + + if (host === undefined) { + // eslint-disable-next-line no-console + console.log(`Preview server listening on \n local: ${address.local[0]} \t\n network: ${address.network[0]}\n`); + } else { + // eslint-disable-next-line no-console + console.log(`Preview server listening on ${address.local[0]}`); + } - // eslint-disable-next-line no-console - console.log(`Preview server listening on http://${host}:${port}`); return server; }; diff --git a/packages/integrations/node/src/standalone.ts b/packages/integrations/node/src/standalone.ts index 68b2cebcdf13..ff1a0f6939ff 100644 --- a/packages/integrations/node/src/standalone.ts +++ b/packages/integrations/node/src/standalone.ts @@ -4,6 +4,7 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { createServer } from './http-server.js'; import middleware from './nodeMiddleware.js'; +import { getNetworkAddress } from './get-network-address.js' import type { Options } from './types'; function resolvePaths(options: Options) { @@ -55,9 +56,16 @@ export default function startServer(app: NodeApp, options: Options) { ); const protocol = server.server instanceof https.Server ? 'https' : 'http'; + const address = getNetworkAddress(protocol, host, port) - // eslint-disable-next-line no-console - console.log(`Server listening on ${protocol}://${host}:${port}`); + if (host === undefined) { + // eslint-disable-next-line no-console + console.log( + `Preview server listening on \n local: ${address.local[0]} \t\n network: ${address.network[0]}\n`); + } else { + // eslint-disable-next-line no-console + console.log(`Preview server listening on ${address.local[0]}`); + } return { server,