From 9ec96b0f966af7eae3e326a374a5c40053d1138b Mon Sep 17 00:00:00 2001 From: BitterGourd <91231822+gaoachao@users.noreply.github.com> Date: Thu, 13 Mar 2025 19:59:59 +0800 Subject: [PATCH 1/4] feat(rspeedy): support server.base --- packages/rspeedy/core/etc/rspeedy.api.md | 1 + .../rspeedy/core/src/config/rsbuild/index.ts | 5 +++++ .../rspeedy/core/src/config/server/index.ts | 21 +++++++++++++++++++ .../rspeedy/core/test/config/server.test-d.ts | 5 +++++ .../rspeedy/core/test/config/validate.test.ts | 21 +++++++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/packages/rspeedy/core/etc/rspeedy.api.md b/packages/rspeedy/core/etc/rspeedy.api.md index ac78a4be14..d9445f50c4 100644 --- a/packages/rspeedy/core/etc/rspeedy.api.md +++ b/packages/rspeedy/core/etc/rspeedy.api.md @@ -254,6 +254,7 @@ export type RspeedyInstance = RsbuildInstance & { // @public export interface Server { + base?: string; headers?: Record | undefined; host?: string | undefined; port?: number | undefined; diff --git a/packages/rspeedy/core/src/config/rsbuild/index.ts b/packages/rspeedy/core/src/config/rsbuild/index.ts index 72f40e50af..1edbcf1166 100644 --- a/packages/rspeedy/core/src/config/rsbuild/index.ts +++ b/packages/rspeedy/core/src/config/rsbuild/index.ts @@ -70,13 +70,18 @@ export function toRsbuildConfig( tsconfigPath: config.source?.tsconfigPath, }, server: { + base: config.server?.base, + headers: config.server?.headers, + host: config.server?.host, + port: config.server?.port, }, plugins: config.plugins, performance: { chunkSplit: config.performance?.chunkSplit, + removeConsole: toRsbuildRemoveConsole(config) as | ConsoleType[] | false diff --git a/packages/rspeedy/core/src/config/server/index.ts b/packages/rspeedy/core/src/config/server/index.ts index ae40885f4b..d602d10c09 100644 --- a/packages/rspeedy/core/src/config/server/index.ts +++ b/packages/rspeedy/core/src/config/server/index.ts @@ -7,6 +7,27 @@ * @public */ export interface Server { + /** + * Configure the base path of the server. + * + * @remarks + * By default, the base path of the server is `/`, and users can access lynx bundle through `http://:/main.lynx.bundle` + * + * If you want to access lynx bundle through `http://:/foo/main.lynx.bundle`, you can change `server.base` to `/foo` + * + * @example + * + * ```js + * import { defineConfig } from '@lynx-js/rspeedy' + * export default defineConfig({ + * server: { + * base: '/foo' + * }, + * }) + * ``` + */ + base?: string | undefined + /** * Adds headers to all responses. * diff --git a/packages/rspeedy/core/test/config/server.test-d.ts b/packages/rspeedy/core/test/config/server.test-d.ts index 96a500be55..2faae0af30 100644 --- a/packages/rspeedy/core/test/config/server.test-d.ts +++ b/packages/rspeedy/core/test/config/server.test-d.ts @@ -6,6 +6,11 @@ import { assertType, describe, test } from 'vitest' import type { Server } from '../../src/index.js' describe('Config - Server', () => { + test('server.base', () => { + assertType({}) + assertType({ base: 'foo' }) + }) + test('server.headers', () => { assertType({}) assertType({ diff --git a/packages/rspeedy/core/test/config/validate.test.ts b/packages/rspeedy/core/test/config/validate.test.ts index 1755bb99be..d61c709b3b 100644 --- a/packages/rspeedy/core/test/config/validate.test.ts +++ b/packages/rspeedy/core/test/config/validate.test.ts @@ -1553,6 +1553,7 @@ describe('Config Validation', () => { test('valid type', () => { const cases: Server[] = [ {}, + { base: 'foo' }, { headers: {} }, { headers: { foo: 'bar' } }, { headers: { foo: [] } }, @@ -1568,6 +1569,26 @@ describe('Config Validation', () => { }) test('invalid type', () => { + expect(() => validate({ server: { base: 123 } })) + .toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid configuration. + + Invalid config on \`$input.server.base\`. + - Expect to be (string | undefined) + - Got: number + ] + `) + + expect(() => validate({ server: { base: null } })) + .toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid configuration. + + Invalid config on \`$input.server.base\`. + - Expect to be (string | undefined) + - Got: null + ] + `) + expect(() => validate({ server: { headers: null } })) .toThrowErrorMatchingInlineSnapshot(` [Error: Invalid configuration. From 8a8b8ed0f0b0de6e33cd030dbd15c95c2f53db62 Mon Sep 17 00:00:00 2001 From: BitterGourd <91231822+gaoachao@users.noreply.github.com> Date: Thu, 13 Mar 2025 20:43:31 +0800 Subject: [PATCH 2/4] feat(rspeedy): support server.base --- .changeset/thirty-buses-exist.md | 19 +++++++++++++++++++ .../rspeedy/core/src/config/server/index.ts | 4 +++- .../rspeedy/core/src/plugins/dev.plugin.ts | 7 +++++++ .../rspeedy/core/test/config/server.test-d.ts | 2 +- .../rspeedy/core/test/config/validate.test.ts | 3 ++- 5 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 .changeset/thirty-buses-exist.md diff --git a/.changeset/thirty-buses-exist.md b/.changeset/thirty-buses-exist.md new file mode 100644 index 0000000000..3c8f2de295 --- /dev/null +++ b/.changeset/thirty-buses-exist.md @@ -0,0 +1,19 @@ +--- +"@lynx-js/rspeedy": patch +--- + +Support configure the base path of the server. + +By default, the base path of the server is `/`, and users can access lynx bundle through `http://:/main.lynx.bundle` +If you want to access lynx bundle through `http://:/foo/main.lynx.bundle`, you can change `server.base` to `/foo` + +example: + +```js +import { defineConfig } from '@lynx-js/rspeedy'; +export default defineConfig({ + server: { + base: '/dist', + }, +}); +``` diff --git a/packages/rspeedy/core/src/config/server/index.ts b/packages/rspeedy/core/src/config/server/index.ts index d602d10c09..844fee4e37 100644 --- a/packages/rspeedy/core/src/config/server/index.ts +++ b/packages/rspeedy/core/src/config/server/index.ts @@ -15,13 +15,15 @@ export interface Server { * * If you want to access lynx bundle through `http://:/foo/main.lynx.bundle`, you can change `server.base` to `/foo` * + * you can refer to {@link https://rsbuild.dev/config/server/base | server.base } for more information. + * * @example * * ```js * import { defineConfig } from '@lynx-js/rspeedy' * export default defineConfig({ * server: { - * base: '/foo' + * base: '/dist' * }, * }) * ``` diff --git a/packages/rspeedy/core/src/plugins/dev.plugin.ts b/packages/rspeedy/core/src/plugins/dev.plugin.ts index 7c56f17510..4a1e7c2994 100644 --- a/packages/rspeedy/core/src/plugins/dev.plugin.ts +++ b/packages/rspeedy/core/src/plugins/dev.plugin.ts @@ -61,6 +61,13 @@ export function pluginDev( } } + if (server?.base) { + if ((assetPrefix as string).endsWith('/')) { + assetPrefix = (assetPrefix as string).slice(0, -1) + } + assetPrefix = `${assetPrefix}${server.base}/` + } + debug(`dev.assetPrefix is normalized to ${assetPrefix}`) api.modifyRsbuildConfig((config, { mergeRsbuildConfig }) => { diff --git a/packages/rspeedy/core/test/config/server.test-d.ts b/packages/rspeedy/core/test/config/server.test-d.ts index 2faae0af30..8c445a1b06 100644 --- a/packages/rspeedy/core/test/config/server.test-d.ts +++ b/packages/rspeedy/core/test/config/server.test-d.ts @@ -8,7 +8,7 @@ import type { Server } from '../../src/index.js' describe('Config - Server', () => { test('server.base', () => { assertType({}) - assertType({ base: 'foo' }) + assertType({ base: '/foo' }) }) test('server.headers', () => { diff --git a/packages/rspeedy/core/test/config/validate.test.ts b/packages/rspeedy/core/test/config/validate.test.ts index d61c709b3b..b5e58698c8 100644 --- a/packages/rspeedy/core/test/config/validate.test.ts +++ b/packages/rspeedy/core/test/config/validate.test.ts @@ -1553,7 +1553,8 @@ describe('Config Validation', () => { test('valid type', () => { const cases: Server[] = [ {}, - { base: 'foo' }, + { base: '/foo' }, + { base: '/bar' }, { headers: {} }, { headers: { foo: 'bar' } }, { headers: { foo: [] } }, From 6c5e77aa72e72df3025d5b3d218bf59e39cad2a2 Mon Sep 17 00:00:00 2001 From: BitterGourd <91231822+gaoachao@users.noreply.github.com> Date: Thu, 13 Mar 2025 21:04:36 +0800 Subject: [PATCH 3/4] feat(rspeedy): support server.base --- .../core/test/plugins/dev.plugin.test.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/rspeedy/core/test/plugins/dev.plugin.test.ts b/packages/rspeedy/core/test/plugins/dev.plugin.test.ts index 65cec8930b..f7ee8eafc3 100644 --- a/packages/rspeedy/core/test/plugins/dev.plugin.test.ts +++ b/packages/rspeedy/core/test/plugins/dev.plugin.test.ts @@ -375,4 +375,45 @@ describe('Plugins - Dev', () => { ], }) }) + + test('server.base without /', async () => { + try { + const rsbuild = await createStubRspeedy({ + server: { + base: 'dist', + }, + }) + + await rsbuild.unwrapConfig() + } catch (error) { + expect(error).toMatchInlineSnapshot( + `[Error: [rsbuild:config] The "server.base" option should start with a slash, for example: "/base"]`, + ) + } + }) + + test('dev.assetPrefix with server.base', async () => { + const rsbuild = await createStubRspeedy({ + dev: { + assetPrefix: 'http://example.com/', + }, + server: { + base: '/dist', + }, + }) + + const config = await rsbuild.unwrapConfig() + + expect(typeof config.output?.publicPath).toBe('string') + + expect(config.output?.publicPath).toContain('http://example.com/') + expect(config.output?.publicPath).toContain('/dist/') + + const { port, hostname, pathname } = new URL(config.output!.publicPath!) + + expect(port).toBe('') + expect(isIP(hostname)).toBe(0) + expect(hostname).toBe('example.com') + expect(pathname).toBe('/dist/') + }) }) From f0a057fda966e3eff4686b8a87e88a5989ea9457 Mon Sep 17 00:00:00 2001 From: BitterGourd <91231822+gaoachao@users.noreply.github.com> Date: Thu, 13 Mar 2025 21:07:38 +0800 Subject: [PATCH 4/4] feat(rspeedy): support server.base --- packages/rspeedy/core/etc/rspeedy.api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rspeedy/core/etc/rspeedy.api.md b/packages/rspeedy/core/etc/rspeedy.api.md index d9445f50c4..4996477349 100644 --- a/packages/rspeedy/core/etc/rspeedy.api.md +++ b/packages/rspeedy/core/etc/rspeedy.api.md @@ -254,7 +254,7 @@ export type RspeedyInstance = RsbuildInstance & { // @public export interface Server { - base?: string; + base?: string | undefined; headers?: Record | undefined; host?: string | undefined; port?: number | undefined;