diff --git a/packages/plugin/vite/spec/config/vite.base.config.spec.ts b/packages/plugin/vite/spec/config/vite.base.config.spec.ts index eecfc4e255..2a05abe4dd 100644 --- a/packages/plugin/vite/spec/config/vite.base.config.spec.ts +++ b/packages/plugin/vite/spec/config/vite.base.config.spec.ts @@ -113,6 +113,47 @@ describe('vite.base.config', () => { expect(define1).toEqual(define2); }); + it('getBuildDefine:serve with custom server host', async () => { + const hosts = ['127.0.0.1', '0.0.0.0']; + const servers = await Promise.all( + forgeConfig.renderer.map(({ name }, index) => + createServer({ + publicDir: false, + server: { host: hosts[index] }, + plugins: [pluginExposeRenderer(name)], + }), + ), + ); + let port = 5183; + + for (const server of servers) { + await server.listen(port); + port++; + } + + const define1 = getBuildDefine({ + command: 'serve', + mode: 'development', + root: configRoot, + forgeConfig, + forgeConfigSelf: forgeConfig.build[0], + }); + const define2 = { + // Custom string hosts are exposed as-is. + MAIN_WINDOW_VITE_DEV_SERVER_URL: '"http://127.0.0.1:5183"', + MAIN_WINDOW_VITE_NAME: '"main_window"', + // Wildcard hosts fall back to localhost. + SECOND_WINDOW_VITE_DEV_SERVER_URL: '"http://localhost:5184"', + SECOND_WINDOW_VITE_NAME: '"second_window"', + }; + + for (const server of servers) { + await server.close(); + } + + expect(define1).toEqual(define2); + }); + describe('pluginHotRestart', () => { let dispose: (() => void) | undefined; diff --git a/packages/plugin/vite/src/config/vite.base.config.ts b/packages/plugin/vite/src/config/vite.base.config.ts index 9551db1484..1d35ec220a 100644 --- a/packages/plugin/vite/src/config/vite.base.config.ts +++ b/packages/plugin/vite/src/config/vite.base.config.ts @@ -75,6 +75,20 @@ export function getBuildDefine(env: ConfigEnv<'build'>) { return define; } +/** + * Resolve the host to use in the dev server URL exposed to the main process. + * Wildcard hosts (`true`, `0.0.0.0`, `::`) are mapped to `localhost` since the + * main process runs on the same machine and wildcard addresses are not + * reliably loadable in Chromium. + */ +function resolveDevHost(host: string | boolean | undefined): string { + if (typeof host !== 'string' || host === '0.0.0.0' || host === '::') { + return 'localhost'; + } + // IPv6 literals must be bracketed in URLs. + return host.includes(':') ? `[${host}]` : host; +} + export function pluginExposeRenderer(name: string): Plugin { const { VITE_DEV_SERVER_URL } = getDefineKeys([name])[name]; @@ -88,7 +102,7 @@ export function pluginExposeRenderer(name: string): Plugin { const addressInfo = server.httpServer?.address() as AddressInfo; // Expose env constant for main process use. viteDevServerUrls[VITE_DEV_SERVER_URL] = - `http://localhost:${addressInfo?.port}`; + `http://${resolveDevHost(server.config.server.host)}:${addressInfo?.port}`; }); }, };