diff --git a/packages/rstack/rstack.config.ts b/packages/rstack/rstack.config.ts index 650c9379..09910407 100644 --- a/packages/rstack/rstack.config.ts +++ b/packages/rstack/rstack.config.ts @@ -11,6 +11,7 @@ define.test(async () => { // Temporary projects may contain files that match Rstest's test glob. exclude: ['**/test-temp-*/**'], extends: withRslibConfig(), + testTimeout: 30_000, source: { tsconfigPath: './tests/tsconfig.json', }, diff --git a/packages/rstack/src/rspressConfig.ts b/packages/rstack/src/rspressConfig.ts index ed5efd59..0bf6a60d 100644 --- a/packages/rstack/src/rspressConfig.ts +++ b/packages/rstack/src/rspressConfig.ts @@ -1,3 +1,4 @@ +import type { WatchFiles } from '@rsbuild/core'; import type { UserConfig } from '@rspress/core'; import { loadRstackConfig, type Configs } from './config.ts'; @@ -13,6 +14,30 @@ const resolveRspressConfig = async (configs: Configs): Promise => { }; export default async (): Promise => { - const { configs } = await loadRstackConfig(); - return resolveRspressConfig(configs); + const { configs, filePath, dependencies } = await loadRstackConfig(); + const config = await resolveRspressConfig(configs); + + if (!filePath) { + return config; + } + + const watchFiles = config.builderConfig?.dev?.watchFiles; + const watchConfig: WatchFiles = { + paths: [filePath, ...dependencies], + type: 'restart', + }; + + return { + ...config, + builderConfig: { + ...config.builderConfig, + dev: { + ...config.builderConfig?.dev, + watchFiles: [ + ...(watchFiles ? (Array.isArray(watchFiles) ? watchFiles : [watchFiles]) : []), + watchConfig, + ], + }, + }, + }; }; diff --git a/packages/rstack/tests/config/define-doc/index.test.ts b/packages/rstack/tests/config/define-doc/index.test.ts index 58ce1fc4..464e7580 100644 --- a/packages/rstack/tests/config/define-doc/index.test.ts +++ b/packages/rstack/tests/config/define-doc/index.test.ts @@ -12,4 +12,4 @@ test('should build docs with define.doc config', async ({ prepareDist, execCli, const output = getFileContent(files, 'index.html'); expect(output).toContain(expectedText); -}, 30_000); +}); diff --git a/packages/rstack/tests/config/reload-app-config/index.test.ts b/packages/rstack/tests/config/reload-app-config/index.test.ts index cdf62067..a7f9ab93 100644 --- a/packages/rstack/tests/config/reload-app-config/index.test.ts +++ b/packages/rstack/tests/config/reload-app-config/index.test.ts @@ -45,7 +45,7 @@ define.app({ ); await waitForFile(dist2); -}, 30_000); +}); test('should reload config when an imported file changes', async ({ execCliAsync, logHelper }) => { const configFile = path.join(import.meta.dirname, 'test-temp-import.config.ts'); @@ -70,4 +70,4 @@ define.app({ await writeFile(importedFile, '// changed\n'); await logHelper.expectLog('restarting server as test-temp-imported.ts changed'); -}, 30_000); +}); diff --git a/packages/rstack/tests/config/reload-doc-config/docs/index.md b/packages/rstack/tests/config/reload-doc-config/docs/index.md new file mode 100644 index 00000000..f5a6303d --- /dev/null +++ b/packages/rstack/tests/config/reload-doc-config/docs/index.md @@ -0,0 +1 @@ +# Reload doc config diff --git a/packages/rstack/tests/config/reload-doc-config/index.test.ts b/packages/rstack/tests/config/reload-doc-config/index.test.ts new file mode 100644 index 00000000..0b00474b --- /dev/null +++ b/packages/rstack/tests/config/reload-doc-config/index.test.ts @@ -0,0 +1,80 @@ +import { writeFile } from 'node:fs/promises'; +import path from 'node:path'; +import { getRandomPort } from '@rstackjs/test-utils'; +import { test } from '#test-helpers'; + +test('should restart doc dev server when Rstack config changes', async ({ + execCliAsync, + logHelper, +}) => { + const configFile = path.join(import.meta.dirname, 'test-temp-rstack.config.ts'); + const userWatchFile = path.join(import.meta.dirname, 'test-temp-user-watch.txt'); + + const writeConfig = (title: string) => + writeFile( + configFile, + `import { define } from 'rstack'; + +define.doc({ + root: 'docs', + title: '${title}', + builderConfig: { + dev: { + watchFiles: { + paths: ${JSON.stringify(userWatchFile)}, + type: 'restart', + }, + }, + }, +}); +`, + ); + + await writeFile(userWatchFile, 'initial\n'); + await writeConfig('before config change'); + + execCliAsync(`doc --config test-temp-rstack.config.ts --port ${await getRandomPort()}`); + await logHelper.expectBuildEnd(); + logHelper.clearLogs(); + + await writeConfig('after config change'); + + await logHelper.expectLog('restarting server as test-temp-rstack.config.ts changed'); + await logHelper.expectBuildEnd(); + logHelper.clearLogs(); + + await writeFile(userWatchFile, 'changed\n'); + + await logHelper.expectLog('restarting server as test-temp-user-watch.txt changed'); + await logHelper.expectBuildEnd(); +}); + +test('should restart doc dev server when an imported config file changes', async ({ + execCliAsync, + logHelper, +}) => { + const configFile = path.join(import.meta.dirname, 'test-temp-import.config.ts'); + const importedFile = path.join(import.meta.dirname, 'test-temp-imported.ts'); + + await writeFile(importedFile, "export const title = 'before import change';\n"); + await writeFile( + configFile, + `import { define } from 'rstack'; +import { title } from './test-temp-imported.ts'; + +define.doc({ + root: 'docs', + title, +}); +`, + ); + + execCliAsync(`doc --config test-temp-import.config.ts --port ${await getRandomPort()}`); + await logHelper.expectBuildEnd(); + logHelper.clearLogs(); + + await writeFile(importedFile, "export const title = 'after import change';\n"); + + await logHelper.expectLog('restarting server as test-temp-imported.ts changed'); + await logHelper.expectBuildEnd(); +});