vitest 0.0.30 → 0.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.gh.md CHANGED
@@ -1,27 +1,41 @@
1
- # vitest
2
-
3
- [![NPM version](https://img.shields.io/npm/v/vitest?color=a1b858&label=)](https://www.npmjs.com/package/vitest)
1
+ <p align="center">
2
+ <img src="https://user-images.githubusercontent.com/11247099/145112184-a9ff6727-661c-439d-9ada-963124a281f7.png" height="200">
3
+ </p>
4
4
 
5
+ <h1 align="center">
6
+ Vitest
7
+ </h1>
8
+ <p align="center">
5
9
  A blazing fast unit test framework powered by Vite.
10
+ <p>
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/vitest"><img src="https://img.shields.io/npm/v/vitest?color=a1b858&label="></a>
13
+ <p>
6
14
 
7
- > **This project is currently in closed beta exclusively for Sponsors.**<br>
15
+ > 💖 **This project is currently in closed beta exclusively for Sponsors.**<br>
8
16
  > Become a Sponsor of [@patak-js](https://github.com/sponsors/patak-js) or [@antfu](https://github.com/sponsors/antfu) to access the source code and issues tracker.
9
17
 
10
18
  > ⚠️ **DISCLAIMER**: Vitest is still in development and not stable yet. It's not recommended to use it in production.
11
19
 
12
20
  > Vitest requires Vite v2.7.0 or above
13
21
 
22
+ [**Join the Discord!**](https://discord.com/invite/2zYZNngd7y)
23
+
14
24
  ## Features
15
25
 
16
- - [Vite](https://vitejs.dev/)'s config, transformers, resolvers, and plugins.
26
+ - [Vite](https://vitejs.dev/)'s config, transformers, resolvers, and plugins. Use the same setup from your app!
17
27
  - [Jest Snapshot](https://jestjs.io/docs/snapshot-testing)
18
- - [Chai](https://www.chaijs.com/) for assertions
19
- - [Sinon](https://sinonjs.org/) for mocking
20
- - [JSDOM](https://github.com/jsdom/jsdom) for DOM mocking
28
+ - [Chai](https://www.chaijs.com/) built-in for assertions, with [jest-expect](https://jestjs.io/docs/expect) compatible APIs.
29
+ - [Smart watch mode](#watch-mode), just like HMR for tests!
30
+ - [Code coverage](#coverage)
31
+ - [Sinon](https://sinonjs.org/) built-in for mocking
32
+ - [JSDOM](https://github.com/jsdom/jsdom) built-in for DOM and browser API mocking
33
+ - Components testing ([Vue example](./test/vue), [React example](./test/react))
21
34
  - Async suite / test, top level await
22
35
  - ESM friendly
23
- - Out-of-box TypeScript support
36
+ - Out-of-box TypeScript / JSX support
24
37
  - Suite and Test filtering (skip, only, todo)
38
+ - Concurrent Tests
25
39
 
26
40
  ```ts
27
41
  import { it, describe, expect, assert } from 'vitest'
@@ -46,6 +60,12 @@ describe('suite name', () => {
46
60
  $ npx vitest
47
61
  ```
48
62
 
63
+ ## Examples
64
+
65
+ - [Unit Testing](./test/core)
66
+ - [Vue Component Testing](./test/vue)
67
+ - [React Component Testing](./test/react)
68
+
49
69
  ## Configuration
50
70
 
51
71
  `vitest` will read your root `vite.config.ts` when it present to match with the plugins and setup as your Vite app. If you want to it to have a different configuration for testing, you could either:
@@ -84,7 +104,7 @@ export default defineConfig({
84
104
 
85
105
  To get TypeScript working with the global APIs, add `vitest/global` to the `types` filed in your `tsconfig.json`
86
106
 
87
- ```json
107
+ ```jsonc
88
108
  // tsconfig.json
89
109
  {
90
110
  "compilerOptions": {
@@ -118,6 +138,31 @@ $ vitest -w
118
138
 
119
139
  Vitest smartly searches the module graph and only rerun the related tests (just like how HMR works in Vite!).
120
140
 
141
+ ## Coverage
142
+
143
+ Vitest works perfectly with [c8](https://github.com/bcoe/c8)
144
+
145
+ ```bash
146
+ $ c8 vitest
147
+ ```
148
+
149
+ ```json
150
+ {
151
+ "scripts": {
152
+ "test": "vitest",
153
+ "coverage": "c8 vitest"
154
+ }
155
+ }
156
+ ```
157
+
158
+ For convenience, we also provide a shorthand for passing `--coverage` option to CLI, which will wrap the process with `c8` for you. Note when using the shorthand, you will lose the ability to pass additional options to `c8`.
159
+
160
+ ```bash
161
+ $ vitest --coverage
162
+ ```
163
+
164
+ For more configuration avaliable, please refer to [c8](https://github.com/bcoe/c8)'s documentation.
165
+
121
166
  ## Filtering
122
167
 
123
168
  ### CLI
@@ -194,18 +239,38 @@ describe('suite', () => {
194
239
  })
195
240
  ```
196
241
 
197
- ## TODO
242
+ ### Running tests concurrently
243
+
244
+ Use `.concurrent` in consecutive tests to run them in parallel
245
+
246
+ ```ts
247
+ // The two tasks marked with concurrent will be run in parallel
248
+ describe('suite', () => {
249
+ it('serial task', () => {
250
+ assert.equal(Math.sqrt(4), 3)
251
+ })
252
+ it.concurrent('concurrent task 1', () => {
253
+ assert.equal(Math.sqrt(4), 3)
254
+ })
255
+ it.concurrent('concurrent task 2', () => {
256
+ assert.equal(Math.sqrt(4), 3)
257
+ })
258
+ })
259
+ ```
260
+
261
+ You can also use `.skip`, `.only`, and `.todo` with concurrent tasks. All the following combinations are valid:
262
+ ```js
263
+ it.concurrent(...)
264
+
265
+ it.skip.concurrent(...)
266
+ it.concurrent.skip(...)
198
267
 
199
- - [x] Reporter & Better output
200
- - [x] Task filter
201
- - [x] Mock
202
- - [x] Global Mode & Types
203
- - [ ] Parallel Executing
204
- - [x] CLI Help
205
- - [x] JSDom
206
- - [x] Watch
207
- - [ ] Source Map
208
- - [ ] Coverage
268
+ it.only.concurrent(...)
269
+ it.concurrent.only(...)
270
+
271
+ it.todo.concurrent(...)
272
+ it.concurrent.todo(...)
273
+ ```
209
274
 
210
275
  ## Sponsors
211
276
 
package/bin/vitest.mjs CHANGED
@@ -1,4 +1,16 @@
1
1
  #!/usr/bin/env node
2
- 'use strict'
3
2
 
4
- import '../dist/node/cli.js'
3
+ import { fileURLToPath } from 'url'
4
+ import { resolve } from 'path'
5
+
6
+ const argv = process.argv.slice(2)
7
+ const filename = fileURLToPath(import.meta.url)
8
+ const entry = resolve(filename, '../../dist/node/cli.js')
9
+
10
+ if (argv.includes('--coverage')) {
11
+ process.argv.splice(2, 0, process.argv[0], entry)
12
+ await import('c8/bin/c8.js')
13
+ }
14
+ else {
15
+ await import('../dist/node/cli.js')
16
+ }
@@ -1,3 +1,4 @@
1
1
  export declare const defaultIncludes: string[];
2
2
  export declare const defaultExcludes: string[];
3
3
  export declare const globalApis: string[];
4
+ export declare const defaultConcurrentTimeout = 5000;
package/dist/constants.js CHANGED
@@ -21,3 +21,4 @@ export const globalApis = [
21
21
  'beforeEach',
22
22
  'afterEach',
23
23
  ];
24
+ export const defaultConcurrentTimeout = 5000;
@@ -5,3 +5,8 @@ const inlineOptions = process.__vite_node__.server.config.test || {};
5
5
  const cliOptions = process.__vitest__.options || {};
6
6
  const options = Object.assign(Object.assign({}, cliOptions), inlineOptions);
7
7
  await run(options);
8
+ const timer = setTimeout(() => {
9
+ // TODO: warn user and maybe error out
10
+ process.exit();
11
+ }, 500);
12
+ timer.unref();
package/dist/node/node.js CHANGED
@@ -68,8 +68,10 @@ const stubRequests = {
68
68
  createHotContext() {
69
69
  return {
70
70
  accept: () => { },
71
+ prune: () => { },
71
72
  };
72
73
  },
74
+ updateStyle() { },
73
75
  },
74
76
  };
75
77
  async function transform(server, id) {
package/dist/run/index.js CHANGED
@@ -98,8 +98,15 @@ export async function runSuite(suite, ctx) {
98
98
  else {
99
99
  try {
100
100
  await callHook(suite, 'beforeAll', [suite]);
101
- for (const t of suite.tasks)
102
- await runTask(t, ctx);
101
+ for (const taskGroup of partitionTasks(suite.tasks)) {
102
+ if (taskGroup[0].concurrent) {
103
+ await Promise.all(taskGroup.map(t => runTask(t, ctx)));
104
+ }
105
+ else {
106
+ for (const t of taskGroup)
107
+ await runTask(t, ctx);
108
+ }
109
+ }
103
110
  await callHook(suite, 'afterAll', [suite]);
104
111
  }
105
112
  catch (e) {
@@ -110,6 +117,25 @@ export async function runSuite(suite, ctx) {
110
117
  }
111
118
  await ((_b = reporter.onSuiteEnd) === null || _b === void 0 ? void 0 : _b.call(reporter, suite, ctx));
112
119
  }
120
+ /**
121
+ * Partition consecutive serial and concurrent tasks in groups
122
+ */
123
+ function partitionTasks(tasks) {
124
+ let taskGroup = [];
125
+ const groupedTasks = [];
126
+ for (const task of tasks) {
127
+ if (taskGroup.length === 0 || !!task.concurrent === !!taskGroup[0].concurrent) {
128
+ taskGroup.push(task);
129
+ }
130
+ else {
131
+ groupedTasks.push(taskGroup);
132
+ taskGroup = [task];
133
+ }
134
+ }
135
+ if (taskGroup.length > 0)
136
+ groupedTasks.push(taskGroup);
137
+ return groupedTasks;
138
+ }
113
139
  export async function runFile(file, ctx) {
114
140
  var _a, _b;
115
141
  const { reporter } = ctx;
@@ -185,7 +211,7 @@ export async function run(config) {
185
211
  snapshotManager.saveSnap();
186
212
  await ((_c = reporter.onFinished) === null || _c === void 0 ? void 0 : _c.call(reporter, ctx));
187
213
  if (config.watch)
188
- startWatcher(ctx);
214
+ await startWatcher(ctx);
189
215
  }
190
216
  export async function startWatcher(ctx) {
191
217
  var _a;
@@ -196,6 +222,7 @@ export async function startWatcher(ctx) {
196
222
  const seen = new Set();
197
223
  const { server, moduleCache } = process.__vite_node__;
198
224
  server.watcher.on('change', async (id) => {
225
+ id = normalizePath(id);
199
226
  getDependencyTests(id, ctx, changedTests, seen);
200
227
  seen.forEach(i => moduleCache.delete(i));
201
228
  seen.clear();
@@ -219,6 +246,14 @@ export async function startWatcher(ctx) {
219
246
  await ((_c = reporter.onWatcherStart) === null || _c === void 0 ? void 0 : _c.call(reporter, ctx));
220
247
  }, 100);
221
248
  });
249
+ // add an empty promise so it never resolves
250
+ await new Promise(() => { });
251
+ }
252
+ function normalizePath(path) {
253
+ const normalized = path.replace(/\\/g, '/');
254
+ if (normalized.startsWith('/'))
255
+ return normalized;
256
+ return `/${normalized}`;
222
257
  }
223
258
  function getDependencyTests(id, ctx, set = new Set(), seen = new Set()) {
224
259
  if (seen.has(id) || set.has(id))
package/dist/suite.d.ts CHANGED
@@ -2,9 +2,24 @@ import { SuiteCollector, TestFactory, TestFunction, Suite } from './types';
2
2
  export declare const defaultSuite: SuiteCollector;
3
3
  export declare const test: {
4
4
  (name: string, fn: TestFunction): void;
5
- skip(name: string, fn: TestFunction): void;
6
- only(name: string, fn: TestFunction): void;
7
- todo(name: string): void;
5
+ concurrent: {
6
+ (name: string, fn: TestFunction, timeout?: number | undefined): void;
7
+ skip(name: string, fn: TestFunction, timeout?: number | undefined): void;
8
+ only(name: string, fn: TestFunction, timeout?: number | undefined): void;
9
+ todo(name: string): void;
10
+ };
11
+ skip: {
12
+ (name: string, fn: TestFunction): void;
13
+ concurrent(name: string, fn: TestFunction, timeout?: number | undefined): void;
14
+ };
15
+ only: {
16
+ (name: string, fn: TestFunction): void;
17
+ concurrent(name: string, fn: TestFunction, timeout?: number | undefined): void;
18
+ };
19
+ todo: {
20
+ (name: string): void;
21
+ concurrent(name: string): void;
22
+ };
8
23
  };
9
24
  export declare function suite(suiteName: string, factory?: TestFactory): SuiteCollector;
10
25
  export declare namespace suite {
@@ -15,9 +30,24 @@ export declare namespace suite {
15
30
  export declare const describe: typeof suite;
16
31
  export declare const it: {
17
32
  (name: string, fn: TestFunction): void;
18
- skip(name: string, fn: TestFunction): void;
19
- only(name: string, fn: TestFunction): void;
20
- todo(name: string): void;
33
+ concurrent: {
34
+ (name: string, fn: TestFunction, timeout?: number | undefined): void;
35
+ skip(name: string, fn: TestFunction, timeout?: number | undefined): void;
36
+ only(name: string, fn: TestFunction, timeout?: number | undefined): void;
37
+ todo(name: string): void;
38
+ };
39
+ skip: {
40
+ (name: string, fn: TestFunction): void;
41
+ concurrent(name: string, fn: TestFunction, timeout?: number | undefined): void;
42
+ };
43
+ only: {
44
+ (name: string, fn: TestFunction): void;
45
+ concurrent(name: string, fn: TestFunction, timeout?: number | undefined): void;
46
+ };
47
+ todo: {
48
+ (name: string): void;
49
+ concurrent(name: string): void;
50
+ };
21
51
  };
22
52
  export declare const beforeAll: (fn: Suite['hooks']['beforeAll'][0]) => void;
23
53
  export declare const afterAll: (fn: Suite['hooks']['afterAll'][0]) => void;
package/dist/suite.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { context } from './context';
2
+ import { defaultConcurrentTimeout } from './constants';
2
3
  export const defaultSuite = suite('');
3
4
  function getCurrentSuite() {
4
5
  return context.currentSuite || defaultSuite;
@@ -16,6 +17,16 @@ function createSuiteCollector(name, factory = () => { }, mode) {
16
17
  afterEach: [],
17
18
  },
18
19
  };
20
+ const test = createTestCollector((name, fn, mode, concurrent) => {
21
+ queue.push({
22
+ name,
23
+ mode,
24
+ concurrent,
25
+ suite: {},
26
+ state: (mode !== 'run' && mode !== 'only') ? mode : undefined,
27
+ fn,
28
+ });
29
+ });
19
30
  const collector = {
20
31
  name,
21
32
  mode,
@@ -27,21 +38,6 @@ function createSuiteCollector(name, factory = () => { }, mode) {
27
38
  function addHook(name, ...fn) {
28
39
  suiteBase.hooks[name].push(...fn);
29
40
  }
30
- function collectTask(name, fn, mode) {
31
- queue.push({
32
- name,
33
- mode,
34
- suite: {},
35
- state: (mode !== 'run' && mode !== 'only') ? mode : undefined,
36
- fn,
37
- });
38
- }
39
- function test(name, fn) {
40
- collectTask(name, fn, 'run');
41
- }
42
- test.skip = (name, fn) => collectTask(name, fn, 'skip');
43
- test.only = (name, fn) => collectTask(name, fn, 'only');
44
- test.todo = (name) => collectTask(name, () => { }, 'todo');
45
41
  function clear() {
46
42
  queue.length = 0;
47
43
  factoryQueue.length = 0;
@@ -64,11 +60,66 @@ function createSuiteCollector(name, factory = () => { }, mode) {
64
60
  context.suites.push(collector);
65
61
  return collector;
66
62
  }
63
+ function createConcurrentOptions(timeout) {
64
+ return { timeout: timeout !== null && timeout !== void 0 ? timeout : defaultConcurrentTimeout };
65
+ }
66
+ function createTestCollector(collectTask) {
67
+ function test(name, fn) {
68
+ collectTask(name, fn, 'run');
69
+ }
70
+ test.concurrent = concurrent;
71
+ test.skip = skip;
72
+ test.only = only;
73
+ test.todo = todo;
74
+ function concurrent(name, fn, timeout) {
75
+ collectTask(name, fn, 'run', createConcurrentOptions(timeout));
76
+ }
77
+ concurrent.skip = (name, fn, timeout) => collectTask(name, fn, 'skip', createConcurrentOptions(timeout));
78
+ concurrent.only = (name, fn, timeout) => collectTask(name, fn, 'only', createConcurrentOptions(timeout));
79
+ concurrent.todo = todo;
80
+ function skip(name, fn) {
81
+ collectTask(name, fn, 'skip');
82
+ }
83
+ skip.concurrent = concurrent.skip;
84
+ function only(name, fn) {
85
+ collectTask(name, fn, 'only');
86
+ }
87
+ only.concurrent = concurrent.only;
88
+ function todo(name) {
89
+ collectTask(name, () => { }, 'todo');
90
+ }
91
+ todo.concurrent = todo;
92
+ return test;
93
+ }
67
94
  // apis
68
- export const test = (name, fn) => getCurrentSuite().test(name, fn);
69
- test.skip = (name, fn) => getCurrentSuite().test.skip(name, fn);
70
- test.only = (name, fn) => getCurrentSuite().test.only(name, fn);
71
- test.todo = (name) => getCurrentSuite().test.todo(name);
95
+ export const test = (function () {
96
+ function test(name, fn) {
97
+ return getCurrentSuite().test(name, fn);
98
+ }
99
+ function concurrent(name, fn, timeout) {
100
+ return getCurrentSuite().test.concurrent(name, fn, timeout);
101
+ }
102
+ concurrent.skip = (name, fn, timeout) => getCurrentSuite().test.concurrent.skip(name, fn, timeout);
103
+ concurrent.only = (name, fn, timeout) => getCurrentSuite().test.concurrent.only(name, fn, timeout);
104
+ concurrent.todo = (name) => getCurrentSuite().test.concurrent.todo(name);
105
+ function skip(name, fn) {
106
+ return getCurrentSuite().test.skip(name, fn);
107
+ }
108
+ skip.concurrent = (name, fn, timeout) => getCurrentSuite().test.skip.concurrent(name, fn, timeout);
109
+ function only(name, fn) {
110
+ return getCurrentSuite().test.only(name, fn);
111
+ }
112
+ only.concurrent = (name, fn, timeout) => getCurrentSuite().test.only.concurrent(name, fn, timeout);
113
+ function todo(name) {
114
+ return getCurrentSuite().test.todo(name);
115
+ }
116
+ todo.concurrent = (name) => getCurrentSuite().test.todo.concurrent(name);
117
+ test.concurrent = concurrent;
118
+ test.skip = skip;
119
+ test.only = only;
120
+ test.todo = todo;
121
+ return test;
122
+ })();
72
123
  export function suite(suiteName, factory) {
73
124
  return createSuiteCollector(suiteName, factory, 'run');
74
125
  }
package/dist/types.d.ts CHANGED
@@ -64,9 +64,13 @@ export interface ResolvedConfig extends Required<UserOptions> {
64
64
  }
65
65
  export declare type RunMode = 'run' | 'skip' | 'only' | 'todo';
66
66
  export declare type TaskState = RunMode | 'pass' | 'fail';
67
+ export interface ConcurrentOptions {
68
+ timeout: number;
69
+ }
67
70
  export interface Task {
68
71
  name: string;
69
72
  mode: RunMode;
73
+ concurrent?: ConcurrentOptions;
70
74
  suite: Suite;
71
75
  fn: () => Awaitable<void>;
72
76
  file?: File;
@@ -74,11 +78,30 @@ export interface Task {
74
78
  error?: unknown;
75
79
  }
76
80
  export declare type TestFunction = () => Awaitable<void>;
81
+ interface ConcurrentCollector {
82
+ (name: string, fn: TestFunction, timeout?: number): void;
83
+ only: (name: string, fn: TestFunction, timeout?: number) => void;
84
+ skip: (name: string, fn: TestFunction, timeout?: number) => void;
85
+ todo: (name: string) => void;
86
+ }
87
+ interface OnlyCollector {
88
+ (name: string, fn: TestFunction): void;
89
+ concurrent: (name: string, fn: TestFunction, timeout?: number) => void;
90
+ }
91
+ interface SkipCollector {
92
+ (name: string, fn: TestFunction): void;
93
+ concurrent: (name: string, fn: TestFunction, timeout?: number) => void;
94
+ }
95
+ interface TodoCollector {
96
+ (name: string): void;
97
+ concurrent: (name: string) => void;
98
+ }
77
99
  export interface TestCollector {
78
100
  (name: string, fn: TestFunction): void;
79
- only: (name: string, fn: TestFunction) => void;
80
- skip: (name: string, fn: TestFunction) => void;
81
- todo: (name: string) => void;
101
+ concurrent: ConcurrentCollector;
102
+ only: OnlyCollector;
103
+ skip: SkipCollector;
104
+ todo: TodoCollector;
82
105
  }
83
106
  export declare type HookListener<T extends any[]> = (...args: T) => Awaitable<void>;
84
107
  export interface Suite {
@@ -136,3 +159,4 @@ export interface Reporter {
136
159
  onWatcherStart?: (ctx: RunnerContext) => Awaitable<void>;
137
160
  onWatcherRerun?: (files: string[], trigger: string, ctx: RunnerContext) => Awaitable<void>;
138
161
  }
162
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitest",
3
- "version": "0.0.30",
3
+ "version": "0.0.34",
4
4
  "description": "A blazing fast unit test framework powered by Vite",
5
5
  "keywords": [
6
6
  "vite",
@@ -47,6 +47,8 @@
47
47
  "test": "run-s test:*",
48
48
  "test:core": "node bin/vitest.mjs --dev -r test/core",
49
49
  "test:vue": "node bin/vitest.mjs --dev -r test/vue",
50
+ "test:react": "node bin/vitest.mjs --dev -r test/react",
51
+ "coverage": "node bin/vitest.mjs --dev -r test/core --coverage",
50
52
  "watch": "tsc -p src/tsconfig.json --watch"
51
53
  },
52
54
  "dependencies": {
@@ -54,6 +56,7 @@
54
56
  "@jest/test-result": "^27.4.2",
55
57
  "@types/chai": "^4.2.22",
56
58
  "@types/sinon-chai": "^3.2.6",
59
+ "c8": "^7.10.0",
57
60
  "chai": "^4.3.4",
58
61
  "chai-subset": "^1.6.0",
59
62
  "diff": "^5.0.0",
@@ -70,26 +73,24 @@
70
73
  "source-map": "^0.7.3"
71
74
  },
72
75
  "peerDependencies": {
73
- "vite": "^2.7.0"
76
+ "vite": "^2.7.1"
74
77
  },
75
78
  "devDependencies": {
76
- "@antfu/eslint-config": "^0.12.1",
79
+ "@antfu/eslint-config": "^0.12.2",
77
80
  "@antfu/ni": "^0.11.0",
78
81
  "@types/chai-subset": "^1.3.3",
79
82
  "@types/diff": "^5.0.1",
80
83
  "@types/jsdom": "^16.2.13",
81
84
  "@types/listr": "^0.14.4",
82
- "@types/node": "^16.11.11",
85
+ "@types/node": "^16.11.12",
83
86
  "@types/sade": "^1.7.3",
84
87
  "@types/sinon": "^10.0.6",
85
- "@vitejs/plugin-vue": "^1.10.1",
86
88
  "bumpp": "^7.1.1",
87
- "eslint": "^8.4.0",
89
+ "eslint": "^8.4.1",
88
90
  "esno": "^0.12.1",
89
91
  "npm-run-all": "^4.1.5",
90
92
  "rimraf": "^3.0.2",
91
93
  "typescript": "^4.5.2",
92
- "vite": "^2.7.0",
93
- "vue": "^3.2.24"
94
+ "vite": "^2.7.1"
94
95
  }
95
96
  }