From 9e392976575af59583f1a2efc1da2c673b7efc2b Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sat, 4 Jun 2022 15:19:58 +0300 Subject: [PATCH 1/5] feat: improve watcher performance, add dumbWatchInclude option --- docs/config/index.md | 24 +++++++++++++++++++---- packages/vitest/src/defaults.ts | 3 ++- packages/vitest/src/node/core.ts | 17 +++++++++++++--- packages/vitest/src/node/plugins/index.ts | 3 +++ packages/vitest/src/types/config.ts | 13 +++++++++--- 5 files changed, 49 insertions(+), 11 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 655f7551a832..c1f01a9e196b 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -332,12 +332,28 @@ 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. + +### dumbWatchInclude + +- **Type**: `string[]` +- **Default:** `[]` -Pattern of file paths to be ignored from triggering watch rerun. Glob pattern is not supported. +Glob patter of file paths that will trigger the whole suite rerun. + +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']) +}) +``` ### isolate diff --git a/packages/vitest/src/defaults.ts b/packages/vitest/src/defaults.ts index f8497232a044..044d49d07550 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/**'], + dumbWatchInclude: [], update: false, reporters: [], silent: false, diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index b676735b39d6..581af38b7073 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('ignore: ') + 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.dumbWatchInclude.length) + watcher.add(this.config.dumbWatchInclude) + + 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) || mm.isMatch(id, this.config.watchExclude)) return false + if (mm.isMatch(id, this.config.dumbWatchInclude)) { + 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..569656a7cd2a 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)[] + dumbWatchInclude?: string[] /** * Isolate environment for each test file From b1a40450af0fe1758b74e381782b5c49cf7a0139 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sat, 4 Jun 2022 15:23:50 +0300 Subject: [PATCH 2/5] chore: remove exessive glob check --- packages/vitest/src/node/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 581af38b7073..773bc30240ff 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -386,7 +386,7 @@ 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) || mm.isMatch(id, this.config.watchExclude)) + if (this.changedTests.has(id) || this.invalidates.has(id)) return false if (mm.isMatch(id, this.config.dumbWatchInclude)) { From 7e94b329a960bca7dba5fc1e5c75083c70178aa2 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sat, 4 Jun 2022 15:31:02 +0300 Subject: [PATCH 3/5] chore: add tip for dumbWatchInclude --- docs/config/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/config/index.md b/docs/config/index.md index c1f01a9e196b..98b3b09b4103 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -355,6 +355,10 @@ test('execute a script', async () => { }) ``` +::: tip +Make sure that your files are not excluded by `watchExclude`. +::: + ### isolate - **Type:** `boolean` From 876e5b75f6453d3c8e90f4326952f87b02048a88 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sun, 5 Jun 2022 09:25:13 +0300 Subject: [PATCH 4/5] refactor: rename dumbWatchInclude -> forceRerunTriggers --- docs/config/index.md | 2 +- packages/vitest/src/defaults.ts | 2 +- packages/vitest/src/node/core.ts | 6 +++--- packages/vitest/src/types/config.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 98b3b09b4103..55dcd695976f 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -339,7 +339,7 @@ Beware that the global setup is run in a different global scope if you are using Glob pattern of file paths to be ignored from triggering watch rerun. -### dumbWatchInclude +### forceRerunTriggers - **Type**: `string[]` - **Default:** `[]` diff --git a/packages/vitest/src/defaults.ts b/packages/vitest/src/defaults.ts index 044d49d07550..9521ee7d60f6 100644 --- a/packages/vitest/src/defaults.ts +++ b/packages/vitest/src/defaults.ts @@ -62,7 +62,7 @@ const config = { hookTimeout: 10000, isolate: true, watchExclude: ['**/node_modules/**', '**/dist/**'], - dumbWatchInclude: [], + forceRerunTriggers: [], update: false, reporters: [], silent: false, diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 773bc30240ff..f813d12d0dfc 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -365,8 +365,8 @@ export class Vitest { } const watcher = this.server.watcher - if (this.config.dumbWatchInclude.length) - watcher.add(this.config.dumbWatchInclude) + if (this.config.forceRerunTriggers.length) + watcher.add(this.config.forceRerunTriggers) watcher.unwatch(this.config.watchExclude) @@ -389,7 +389,7 @@ export class Vitest { if (this.changedTests.has(id) || this.invalidates.has(id)) return false - if (mm.isMatch(id, this.config.dumbWatchInclude)) { + if (mm.isMatch(id, this.config.forceRerunTriggers)) { this.state.getFilepaths().forEach(file => this.changedTests.add(file)) return true } diff --git a/packages/vitest/src/types/config.ts b/packages/vitest/src/types/config.ts index 569656a7cd2a..de282baff7d9 100644 --- a/packages/vitest/src/types/config.ts +++ b/packages/vitest/src/types/config.ts @@ -209,7 +209,7 @@ export interface InlineConfig { * * @default [] */ - dumbWatchInclude?: string[] + forceRerunTriggers?: string[] /** * Isolate environment for each test file From a5011c3bbb0529d363658b89de5300d2a3f8b88c Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sun, 5 Jun 2022 09:26:29 +0300 Subject: [PATCH 5/5] chore: cleanup --- packages/vitest/src/node/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index f813d12d0dfc..f9cd5d1df83b 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -123,7 +123,7 @@ export class Vitest { if (this.config.include) this.console.error(c.dim('include: ') + c.yellow(this.config.include.join(comma))) if (this.config.watchExclude) - this.console.error(c.dim('ignore: ') + c.yellow(this.config.watchExclude.join(comma))) + 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')