diff --git a/docs/config/index.md b/docs/config/index.md index b6fcfac0c277..8338c8812fab 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -336,12 +336,32 @@ Beware that the global setup is run in a different global scope if you are using ::: -### watchIgnore +### watchExclude -- **Type:** `(string | RegExp)[]` -- **Default:** `[/\/node_modules\//, /\/dist\//]` +- **Type:** `string[]` +- **Default:** `['**/node_modules/**', '**/dist/**']` + +Glob pattern of file paths to be ignored from triggering watch rerun. + +### forceRerunTriggers + +- **Type**: `string[]` +- **Default:** `[]` + +Glob patter of file paths that will trigger the whole suite rerun. -Pattern of file paths to be ignored from triggering watch rerun. Glob pattern is not supported. +Useful if you are testing calling CLI commands, because Vite cannot construct a module graph: + +```ts +test('execute a script', async () => { + // Vite cannot rerun this test, if content of `dist/index.js` changes + await execa('node', ['dist/index.js']) +}) +``` + +::: tip +Make sure that your files are not excluded by `watchExclude`. +::: ### isolate diff --git a/packages/vitest/src/defaults.ts b/packages/vitest/src/defaults.ts index f8497232a044..9521ee7d60f6 100644 --- a/packages/vitest/src/defaults.ts +++ b/packages/vitest/src/defaults.ts @@ -61,7 +61,8 @@ const config = { testTimeout: 5000, hookTimeout: 10000, isolate: true, - watchIgnore: [/\/node_modules\//, /\/dist\//], + watchExclude: ['**/node_modules/**', '**/dist/**'], + forceRerunTriggers: [], update: false, reporters: [], silent: false, diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index b676735b39d6..f9cd5d1df83b 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -122,8 +122,8 @@ export class Vitest { this.console.error(c.dim('filter: ') + c.yellow(filters.join(comma))) if (this.config.include) this.console.error(c.dim('include: ') + c.yellow(this.config.include.join(comma))) - if (this.config.watchIgnore) - this.console.error(c.dim('ignore: ') + c.yellow(this.config.watchIgnore.join(comma))) + if (this.config.watchExclude) + this.console.error(c.dim('watch exclude: ') + c.yellow(this.config.watchExclude.join(comma))) if (this.config.passWithNoTests) this.log('No test files found, exiting with code 0\n') @@ -364,6 +364,12 @@ export class Vitest { } } const watcher = this.server.watcher + + if (this.config.forceRerunTriggers.length) + watcher.add(this.config.forceRerunTriggers) + + watcher.unwatch(this.config.watchExclude) + watcher.on('change', onChange) watcher.on('unlink', onUnlink) watcher.on('add', onAdd) @@ -380,9 +386,14 @@ export class Vitest { * @returns A value indicating whether rerun is needed (changedTests was mutated) */ private handleFileChanged(id: string): boolean { - if (this.changedTests.has(id) || this.invalidates.has(id) || this.config.watchIgnore.some(i => id.match(i))) + if (this.changedTests.has(id) || this.invalidates.has(id)) return false + if (mm.isMatch(id, this.config.forceRerunTriggers)) { + this.state.getFilepaths().forEach(file => this.changedTests.add(file)) + return true + } + const mod = this.server.moduleGraph.getModuleById(id) if (!mod) return false diff --git a/packages/vitest/src/node/plugins/index.ts b/packages/vitest/src/node/plugins/index.ts index 7ca2aca431fe..8cc0f4239480 100644 --- a/packages/vitest/src/node/plugins/index.ts +++ b/packages/vitest/src/node/plugins/index.ts @@ -77,6 +77,9 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest()) }, server: { ...preOptions.api, + watch: { + ignored: preOptions.watchExclude, + }, open, hmr: false, preTransformRequests: false, diff --git a/packages/vitest/src/types/config.ts b/packages/vitest/src/types/config.ts index ea0143dd8b48..de282baff7d9 100644 --- a/packages/vitest/src/types/config.ts +++ b/packages/vitest/src/types/config.ts @@ -198,11 +198,18 @@ export interface InlineConfig { globalSetup?: string | string[] /** - * Pattern of file paths to be ignore from triggering watch rerun + * Glob pattern of file paths to be ignore from triggering watch rerun + */ + watchExclude?: string[] + + /** + * Glob patter of file paths that will trigger the whole suite rerun * - * @default [/\/node_modules\//, /\/dist\//] + * Useful if you are testing calling CLI commands + * + * @default [] */ - watchIgnore?: (string | RegExp)[] + forceRerunTriggers?: string[] /** * Isolate environment for each test file