diff --git a/packages/core/src/server/open.ts b/packages/core/src/server/open.ts index 762b298d52..45085c6aa6 100644 --- a/packages/core/src/server/open.ts +++ b/packages/core/src/server/open.ts @@ -107,11 +107,15 @@ export function resolveUrl(str: string, base: string): string { const normalizeOpenConfig = ( config: NormalizedConfig, -): { targets: string[]; before?: () => Promise | void } => { +): { + targets: string[]; + before?: () => Promise | void; + skip?: boolean; +} => { const { open } = config.server; if (typeof open === 'boolean') { - return { targets: [] }; + return { targets: [], skip: !open }; } if (typeof open === 'string') { return { targets: [open] }; @@ -138,15 +142,18 @@ export async function open({ routes: Routes; config: NormalizedConfig; clearCache?: boolean; -}): Promise { - const { targets, before } = normalizeOpenConfig(config); +}): Promise { + const { targets, before, skip } = normalizeOpenConfig(config); + if (skip) { + return false; + } // Skip open in codesandbox. After being bundled, the `open` package will // try to call system xdg-open, which will cause an error on codesandbox. // https://github.com/codesandbox/codesandbox-client/issues/6642 const isCodesandbox = process.env.CSB === 'true'; if (isCodesandbox) { - return; + return false; } if (clearCache) { @@ -175,6 +182,7 @@ export async function open({ await before(); } + let opened = false; for (const url of urls) { /** * If an URL has been opened in current process, we will not open it again. @@ -183,6 +191,8 @@ export async function open({ if (!openedURLs.includes(url)) { openBrowser(url); openedURLs.push(url); + opened = true; } } + return opened; } diff --git a/packages/core/tests/open.test.ts b/packages/core/tests/open.test.ts index c5d2b6a3b9..0ed08e4b4d 100644 --- a/packages/core/tests/open.test.ts +++ b/packages/core/tests/open.test.ts @@ -1,4 +1,5 @@ -import { replacePortPlaceholder, resolveUrl } from '../src/server/open'; +import type { NormalizedConfig, NormalizedServerConfig } from '../dist-types'; +import { open, replacePortPlaceholder, resolveUrl } from '../src/server/open'; describe('plugin-open', () => { it('#replacePortPlaceholder - should replace port number correctly', () => { @@ -30,4 +31,30 @@ describe('plugin-open', () => { expect(resolveUrl('//localhost', baseUrl)).toEqual('http://localhost/'); expect(resolveUrl('path', baseUrl)).toEqual('http://localhost/path'); }); + + it('#open - should return false when open parameter is false', async () => { + const result = await open({ + port: 3000, + routes: [], + config: { + server: { + open: false, + } as NormalizedServerConfig, + } as NormalizedConfig, + }); + expect(result).toBe(false); + }); + + it('#open - should return true when open parameter is true', async () => { + const result = await open({ + port: 3000, + routes: [], + config: { + server: { + open: true, + } as NormalizedServerConfig, + } as NormalizedConfig, + }); + expect(result).toBe(false); + }); }); diff --git a/website/docs/en/config/server/open.mdx b/website/docs/en/config/server/open.mdx index 80081e6c6c..f08fb280c3 100644 --- a/website/docs/en/config/server/open.mdx +++ b/website/docs/en/config/server/open.mdx @@ -73,6 +73,16 @@ export default { }; ``` +- Do not open any browser at all: + +```js +export default { + server: { + open: false, + }, +}; +``` + ## Port placeholder The port number that Rsbuild server listens on may change. For example, if the port is in use, Rsbuild will automatically increment the port number until it finds an available port.