Skip to content

Commit 114a993

Browse files
authored
feat!: add support for pool and poolOptions, remove old flags (#4172)
1 parent a5383c2 commit 114a993

File tree

42 files changed

+568
-283
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+568
-283
lines changed

docs/config/index.md

Lines changed: 177 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ Should Vitest process assets (.png, .svg, .jpg, etc) files and resolve them like
249249
This module will have a default export equal to the path to the asset, if no query is specified.
250250

251251
::: warning
252-
At the moment, this option only works with [`experimentalVmThreads`](#experimentalvmthreads) pool.
252+
At the moment, this option only works with [`vmThreads`](#vmthreads) pool.
253253
:::
254254

255255
#### deps.web.transformCss
@@ -262,7 +262,7 @@ Should Vitest process CSS (.css, .scss, .sass, etc) files and resolve them like
262262
If CSS files are disabled with [`css`](#css) options, this option will just silence `ERR_UNKNOWN_FILE_EXTENSION` errors.
263263

264264
::: warning
265-
At the moment, this option only works with [`experimentalVmThreads`](#experimentalvmthreads) pool.
265+
At the moment, this option only works with [`vmThreads`](#vmthreads) pool.
266266
:::
267267

268268
#### deps.web.transformGlobPattern
@@ -275,7 +275,7 @@ Regexp pattern to match external files that should be transformed.
275275
By default, files inside `node_modules` are externalized and not transformed, unless it's CSS or an asset, and corresponding option is not disabled.
276276

277277
::: warning
278-
At the moment, this option only works with [`experimentalVmThreads`](#experimentalvmthreads) pool.
278+
At the moment, this option only works with [`vmThreads`](#vmthreads) pool.
279279
:::
280280

281281
#### deps.registerNodeLoader<NonProjectOption />
@@ -547,7 +547,7 @@ export default defineConfig({
547547

548548
### poolMatchGlobs
549549

550-
- **Type:** `[string, 'threads' | 'child_process' | 'experimentalVmThreads'][]`
550+
- **Type:** `[string, 'threads' | 'forks' | 'VmThreads'][]`
551551
- **Default:** `[]`
552552
- **Version:** Since Vitest 0.29.4
553553

@@ -621,15 +621,28 @@ Custom reporters for output. Reporters can be [a Reporter instance](https://gith
621621
Write test results to a file when the `--reporter=json`, `--reporter=html` or `--reporter=junit` option is also specified.
622622
By providing an object instead of a string you can define individual outputs when using multiple reporters.
623623

624-
### experimentalVmThreads
624+
### pool<NonProjectOption />
625625

626-
- **Type:** `boolean`
627-
- **CLI:** `--experimentalVmThreads`, `--experimental-vm-threads`
628-
- **Version:** Since Vitest 0.34.0
626+
- **Type:** `'threads' | 'forks' | 'vmThreads'`
627+
- **Default:** `'threads'`
628+
- **CLI:** `--pool=threads`
629+
- **Version:** Since Vitest 1.0.0-beta
630+
631+
Pool used to run tests in.
632+
633+
#### threads<NonProjectOption />
634+
635+
Enable multi-threading using [tinypool](https://github.com/tinylibs/tinypool) (a lightweight fork of [Piscina](https://github.com/piscinajs/piscina)). When using threads you are unable to use process related APIs such as `process.chdir()`. Some libraries written in native languages, such as Prisma, `bcrypt` and `canvas`, have problems when running in multiple threads and run into segfaults. In these cases it is adviced to use `forks` pool instead.
629636

630-
Run tests using [VM context](https://nodejs.org/api/vm.html) (inside a sandboxed environment) in a worker pool.
637+
#### forks<NonProjectOption />
631638

632-
This makes tests run faster, but the VM module is unstable when running [ESM code](https://github.com/nodejs/node/issues/37648). Your tests will [leak memory](https://github.com/nodejs/node/issues/33439) - to battle that, consider manually editing [`experimentalVmWorkerMemoryLimit`](#experimentalvmworkermemorylimit) value.
639+
Similar as `threads` pool but uses `child_process` instead of `worker_threads` via [tinypool](https://github.com/tinylibs/tinypool). Communication between tests and main process is not as fast as with `threads` pool. Process related APIs such as `process.chdir()` are available in `forks` pool.
640+
641+
#### vmThreads<NonProjectOption />
642+
643+
Run tests using [VM context](https://nodejs.org/api/vm.html) (inside a sandboxed environment) in a `threads` pool.
644+
645+
This makes tests run faster, but the VM module is unstable when running [ESM code](https://github.com/nodejs/node/issues/37648). Your tests will [leak memory](https://github.com/nodejs/node/issues/33439) - to battle that, consider manually editing [`poolOptions.vmThreads.memoryLimit`](#pooloptions-vmthreads-memorylimit) value.
633646

634647
::: warning
635648
Running code in a sandbox has some advantages (faster tests), but also comes with a number of disadvantages.
@@ -651,83 +664,192 @@ catch (err) {
651664
Please, be aware of these issues when using this option. Vitest team cannot fix any of the issues on our side.
652665
:::
653666

654-
### experimentalVmWorkerMemoryLimit
667+
### poolOptions<NonProjectOption />
655668

656-
- **Type:** `string | number`
657-
- **CLI:** `--experimentalVmWorkerMemoryLimit`, `--experimental-vm-worker-memory-limit`
658-
- **Default:** `1 / CPU Cores`
659-
- **Version:** Since Vitest 0.34.0
669+
- **Type:** `Record<'threads' | 'forks' | 'vmThreads', {}>`
670+
- **Default:** `{}`
671+
- **Version:** Since Vitest 1.0.0-beta
660672

661-
Specifies the memory limit for workers before they are recycled. This value heavily depends on your environment, so it's better to specify it manually instead of relying on the default.
673+
#### poolOptions.threads<NonProjectOption />
662674

663-
This option only affects workers that run tests in [VM context](#experimentalvmthreads).
675+
Options for `threads` pool.
664676

665-
::: tip
666-
The implementation is based on Jest's [`workerIdleMemoryLimit`](https://jestjs.io/docs/configuration#workeridlememorylimit-numberstring).
677+
```ts
678+
import { defineConfig } from 'vitest/config'
667679

668-
The limit can be specified in a number of different ways and whatever the result is `Math.floor` is used to turn it into an integer value:
680+
export default defineConfig({
681+
test: {
682+
poolOptions: {
683+
threads: {
684+
// Threads related options here
685+
}
686+
}
687+
}
688+
})
689+
```
669690

670-
- `<= 1` - The value is assumed to be a percentage of system memory. So 0.5 sets the memory limit of the worker to half of the total system memory
671-
- `\> 1` - Assumed to be a fixed byte value. Because of the previous rule if you wanted a value of 1 byte (I don't know why) you could use 1.1.
672-
- With units
673-
- `50%` - As above, a percentage of total system memory
674-
- `100KB`, `65MB`, etc - With units to denote a fixed memory limit.
675-
- `K` / `KB` - Kilobytes (x1000)
676-
- `KiB` - Kibibytes (x1024)
677-
- `M` / `MB` - Megabytes
678-
- `MiB` - Mebibytes
679-
- `G` / `GB` - Gigabytes
680-
- `GiB` - Gibibytes
681-
:::
691+
##### poolOptions.threads.maxThreads<NonProjectOption />
682692

683-
::: warning
684-
Percentage based memory limit [does not work on Linux CircleCI](https://github.com/jestjs/jest/issues/11956#issuecomment-1212925677) workers due to incorrect system memory being reported.
693+
- **Type:** `number`
694+
- **Default:** _available CPUs_
695+
696+
Maximum number of threads. You can also use `VITEST_MAX_THREADS` environment variable.
697+
698+
##### poolOptions.threads.minThreads<NonProjectOption />
699+
700+
- **Type:** `number`
701+
- **Default:** _available CPUs_
702+
703+
Minimum number of threads. You can also use `VITEST_MIN_THREADS` environment variable.
704+
705+
##### poolOptions.threads.singleThread<NonProjectOption />
706+
707+
- **Type:** `boolean`
708+
- **Default:** `false`
709+
710+
Run all tests with the same environment inside a single worker thread. This will disable built-in module isolation (your source code or [inlined](#deps-inline) code will still be reevaluated for each test), but can improve test performance.
711+
712+
713+
:::warning
714+
Even though this option will force tests to run one after another, this option is different from Jest's `--runInBand`. Vitest uses workers not only for running tests in parallel, but also to provide isolation. By disabling this option, your tests will run sequentially, but in the same global context, so you must provide isolation yourself.
715+
716+
This might cause all sorts of issues, if you are relying on global state (frontend frameworks usually do) or your code relies on environment to be defined separately for each test. But can be a speed boost for your tests (up to 3 times faster), that don't necessarily rely on global state or can easily bypass that.
685717
:::
686718

687-
### threads
719+
##### poolOptions.threads.useAtomics<NonProjectOption />
720+
721+
- **Type:** `boolean`
722+
- **Default:** `false`
723+
724+
Use Atomics to synchronize threads.
725+
726+
This can improve performance in some cases, but might cause segfault in older Node versions.
727+
728+
##### poolOptions.threads.isolate<NonProjectOption />
688729

689730
- **Type:** `boolean`
690731
- **Default:** `true`
691-
- **CLI:** `--threads`, `--threads=false`
692732

693-
Enable multi-threading using [tinypool](https://github.com/tinylibs/tinypool) (a lightweight fork of [Piscina](https://github.com/piscinajs/piscina)). Prior to Vitest 0.29.0, Vitest was still running tests inside worker thread, even if this option was disabled. Since 0.29.0, if this option is disabled, Vitest uses `child_process` to spawn a process to run tests inside, meaning you can use `process.chdir` and other API that was not available inside workers. If you want to revert to the previous behaviour, use `--single-thread` option instead.
733+
Isolate environment for each test file.
734+
735+
#### poolOptions.forks<NonProjectOption />
736+
737+
Options for `forks` pool.
738+
739+
```ts
740+
import { defineConfig } from 'vitest/config'
741+
742+
export default defineConfig({
743+
test: {
744+
poolOptions: {
745+
forks: {
746+
// Forks related options here
747+
}
748+
}
749+
}
750+
})
751+
```
752+
753+
##### poolOptions.forks.maxForks<NonProjectOption />
694754

695-
Disabling this option makes all tests run inside multiple child processes.
755+
- **Type:** `number`
756+
- **Default:** _available CPUs_
696757

697-
### singleThread
758+
Maximum number of forks.
759+
760+
##### poolOptions.forks.minForks<NonProjectOption />
761+
762+
- **Type:** `number`
763+
- **Default:** _available CPUs_
764+
765+
Minimum number of forks.
766+
767+
##### poolOptions.forks.isolate<NonProjectOption />
768+
769+
- **Type:** `boolean`
770+
- **Default:** `true`
771+
772+
Isolate environment for each test file.
773+
774+
##### poolOptions.forks.singleFork<NonProjectOption />
698775

699776
- **Type:** `boolean`
700777
- **Default:** `false`
701-
- **Version:** Since Vitest 0.29.0
702778

703-
Run all tests with the same environment inside a single worker thread. This will disable built-in module isolation (your source code or [inlined](#deps-inline) code will still be reevaluated for each test), but can improve test performance. Before Vitest 0.29.0 this was equivalent to using `--no-threads`.
779+
Run all tests with the same environment inside a single child process. This will disable built-in module isolation (your source code or [inlined](#deps-inline) code will still be reevaluated for each test), but can improve test performance.
704780

705781

706782
:::warning
707-
Even though this option will force tests to run one after another, this option is different from Jest's `--runInBand`. Vitest uses workers not only for running tests in parallel, but also to provide isolation. By disabling this option, your tests will run sequentially, but in the same global context, so you must provide isolation yourself.
783+
Even though this option will force tests to run one after another, this option is different from Jest's `--runInBand`. Vitest uses child processes not only for running tests in parallel, but also to provide isolation. By disabling this option, your tests will run sequentially, but in the same global context, so you must provide isolation yourself.
708784

709785
This might cause all sorts of issues, if you are relying on global state (frontend frameworks usually do) or your code relies on environment to be defined separately for each test. But can be a speed boost for your tests (up to 3 times faster), that don't necessarily rely on global state or can easily bypass that.
710786
:::
711787

712-
### maxThreads<NonProjectOption />
788+
#### poolOptions.vmThreads<NonProjectOption />
789+
790+
Options for `vmThreads` pool.
791+
792+
```ts
793+
import { defineConfig } from 'vitest/config'
794+
795+
export default defineConfig({
796+
test: {
797+
poolOptions: {
798+
vmThreads: {
799+
// VM threads related options here
800+
}
801+
}
802+
}
803+
})
804+
```
805+
806+
##### poolOptions.vmThreads.maxThreads<NonProjectOption />
713807

714808
- **Type:** `number`
715809
- **Default:** _available CPUs_
716810

717811
Maximum number of threads. You can also use `VITEST_MAX_THREADS` environment variable.
718812

719-
### minThreads<NonProjectOption />
813+
##### poolOptions.vmThreads.minThreads<NonProjectOption />
720814

721815
- **Type:** `number`
722816
- **Default:** _available CPUs_
723817

724818
Minimum number of threads. You can also use `VITEST_MIN_THREADS` environment variable.
725819

726-
### useAtomics<NonProjectOption />
820+
##### poolOptions.vmThreads.memoryLimit<NonProjectOption />
821+
822+
- **Type:** `string | number`
823+
- **Default:** `1 / CPU Cores`
824+
825+
Specifies the memory limit for workers before they are recycled. This value heavily depends on your environment, so it's better to specify it manually instead of relying on the default.
826+
827+
::: tip
828+
The implementation is based on Jest's [`workerIdleMemoryLimit`](https://jestjs.io/docs/configuration#workeridlememorylimit-numberstring).
829+
830+
The limit can be specified in a number of different ways and whatever the result is `Math.floor` is used to turn it into an integer value:
831+
832+
- `<= 1` - The value is assumed to be a percentage of system memory. So 0.5 sets the memory limit of the worker to half of the total system memory
833+
- `\> 1` - Assumed to be a fixed byte value. Because of the previous rule if you wanted a value of 1 byte (I don't know why) you could use 1.1.
834+
- With units
835+
- `50%` - As above, a percentage of total system memory
836+
- `100KB`, `65MB`, etc - With units to denote a fixed memory limit.
837+
- `K` / `KB` - Kilobytes (x1000)
838+
- `KiB` - Kibibytes (x1024)
839+
- `M` / `MB` - Megabytes
840+
- `MiB` - Mebibytes
841+
- `G` / `GB` - Gigabytes
842+
- `GiB` - Gibibytes
843+
:::
844+
845+
::: warning
846+
Percentage based memory limit [does not work on Linux CircleCI](https://github.com/jestjs/jest/issues/11956#issuecomment-1212925677) workers due to incorrect system memory being reported.
847+
:::
848+
849+
##### poolOptions.vmThreads.useAtomics<NonProjectOption />
727850

728851
- **Type:** `boolean`
729852
- **Default:** `false`
730-
- **Version:** Since Vitest 0.28.3
731853

732854
Use Atomics to synchronize threads.
733855

@@ -773,7 +895,7 @@ Path to setup files. They will be run before each test file.
773895
Changing setup files will trigger rerun of all tests.
774896
:::
775897

776-
You can use `process.env.VITEST_POOL_ID` (integer-like string) inside to distinguish between threads (will always be `'1'`, if run with `threads: false`).
898+
You can use `process.env.VITEST_POOL_ID` (integer-like string) inside to distinguish between threads.
777899

778900
:::tip
779901
Note, that if you are running [`--threads=false`](#threads), this setup file will be run in the same global scope multiple times. Meaning, that you are accessing the same global object before each test, so make sure you are not doing the same thing more than you need.
@@ -842,16 +964,6 @@ test('execute a script', async () => {
842964
Make sure that your files are not excluded by `watchExclude`.
843965
:::
844966

845-
### isolate
846-
847-
- **Type:** `boolean`
848-
- **Default:** `true`
849-
- **CLI:** `--isolate`, `--isolate=false`
850-
851-
Isolate environment for each test file. Does not work if you disable [`--threads`](#threads).
852-
853-
This options has no effect on [`experimentalVmThreads`](#experimentalvmthreads).
854-
855967
### coverage<NonProjectOption />
856968

857969
You can use [`v8`](https://v8.dev/blog/javascript-code-coverage), [`istanbul`](https://istanbul.js.org/) or [a custom coverage solution](/guide/coverage#custom-coverage-provider) for coverage collection.
@@ -1211,6 +1323,14 @@ Run all tests in a specific browser. Possible options in different providers:
12111323

12121324
Run the browser in a `headless` mode. If you are running Vitest in CI, it will be enabled by default.
12131325

1326+
#### browser.isolate
1327+
1328+
- **Type:** `boolean`
1329+
- **Default:** `true`
1330+
- **CLI:** `--browser`, `--browser.isolate=false`
1331+
1332+
Isolate test environment after each test.
1333+
12141334
#### browser.api
12151335

12161336
- **Type:** `number | { port?, strictPort?, host? }`

docs/guide/debugging.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Setting | Value
4646
--- | ---
4747
Working directory | /path/to/your-project-root
4848
JavaScript file | ./node_modules/vitest/vitest.mjs
49-
Application parameters | run --threads false
49+
Application parameters | run --pool forks
5050

5151
Then run this configuration in debug mode. The IDE will stop at JS/TS breakpoints set in the editor.
5252

@@ -56,12 +56,12 @@ Vitest also supports debugging tests without IDEs. However this requires that te
5656

5757
```sh
5858
# To run in a single worker
59-
vitest --inspect-brk --single-thread
59+
vitest --inspect-brk --pool threads --poolOptions.threads.singleThread
6060

61-
# To run in a child process
62-
vitest --inspect-brk --single-thread --no-threads
61+
# To run in a single child process
62+
vitest --inspect-brk --pool forks --poolOptions.forks.singleFork
6363
```
6464

6565
Once Vitest starts it will stop execution and waits for you to open developer tools that can connect to [NodeJS inspector](https://nodejs.org/en/docs/guides/debugging-getting-started/). You can use Chrome DevTools for this by opening `chrome://inspect` on browser.
6666

67-
In watch mode you can keep the debugger open during test re-runs by using the `--single-thread --isolate false` options.
67+
In watch mode you can keep the debugger open during test re-runs by using the `--poolOptions.threads.isolate false` options.

examples/solid/vite.config.mjs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ import solid from 'vite-plugin-solid'
77
export default defineConfig({
88
test: {
99
environment: 'jsdom',
10-
threads: false,
11-
isolate: false,
10+
pool: 'forks',
11+
poolOptions: {
12+
forks: {
13+
isolate: false,
14+
},
15+
},
1216
},
1317
plugins: [solid()],
1418
resolve: {

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
"test:run": "vitest run -r test/core",
2424
"test:all": "CI=true pnpm -r --stream run test --allowOnly",
2525
"test:ci": "CI=true pnpm -r --stream --filter !test-fails --filter !test-browser --filter !test-esm --filter !test-browser run test --allowOnly",
26-
"test:ci:vm-threads": "CI=true pnpm -r --stream --filter !test-fails --filter !test-single-thread --filter !test-browser --filter !test-esm --filter !test-browser run test --allowOnly --experimental-vm-threads",
27-
"test:ci:no-threads": "CI=true pnpm -r --stream --filter !test-fails --filter !test-coverage --filter !test-watch --filter !test-bail --filter !test-esm --filter !test-browser run test --allowOnly --no-threads",
26+
"test:ci:vm-threads": "CI=true pnpm -r --stream --filter !test-fails --filter !test-coverage --filter !test-single-thread --filter !test-browser --filter !test-esm --filter !test-browser run test --allowOnly --pool vmThreads",
27+
"test:ci:no-threads": "CI=true pnpm -r --stream --filter !test-fails --filter !test-vm-threads --filter !test-coverage --filter !test-watch --filter !test-bail --filter !test-esm --filter !test-browser run test --allowOnly --pool forks",
2828
"typecheck": "tsc --noEmit",
2929
"typecheck:why": "tsc --noEmit --explainFiles > explainTypes.txt",
3030
"ui:build": "vite build packages/ui",

0 commit comments

Comments
 (0)