Skip to content

Commit 5a894aa

Browse files
authored
feat: enable experimentalOptimizer (#3413)
1 parent 0caadf4 commit 5a894aa

File tree

6 files changed

+73
-54
lines changed

6 files changed

+73
-54
lines changed

docs/config/index.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,19 +113,16 @@ Handling for dependencies resolution.
113113
- **Version:** Since Vitest 0.29.0
114114
- **See also:** [Dep Optimization Options](https://vitejs.dev/config/dep-optimization-options.html)
115115

116-
::: warning
117-
This feature is temporarily disabled since Vitest 0.30.0.
118-
:::
119-
120116
Enable dependency optimization. If you have a lot of tests, this might improve their performance.
121117

122118
For `jsdom` and `happy-dom` environments, when Vitest will encounter the external library, it will be bundled into a single file using esbuild and imported as a whole module. This is good for several reasons:
123119

124120
- Importing packages with a lot of imports is expensive. By bundling them into one file we can save a lot of time
125121
- Importing UI libraries is expensive because they are not meant to run inside Node.js
126122
- Your `alias` configuration is now respected inside bundled packages
123+
- Code in your tests is running closer to how it's running in the browser
127124

128-
You can opt-out of this behavior for certain packages with `exclude` option. You can read more about available options in [Vite](https://vitejs.dev/config/dep-optimization-options.html) docs.
125+
Be aware that only packages in `deps.experimentalOptimizer.include` option are bundled (some plugins populate this automatically, like Svelte). You can read more about available options in [Vite](https://vitejs.dev/config/dep-optimization-options.html) docs.
129126

130127
This options also inherits your `optimizeDeps` configuration. If you redefine `include`/`exclude`/`entries` option in `deps.experimentalOptimizer` it will overwrite your `optimizeDeps` when running tests.
131128

packages/vitest/src/node/error.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,12 @@ function printModuleWarningForPackage(logger: Logger, path: string, name: string
169169
+ c.green(`export default {
170170
test: {
171171
deps: {
172-
inline: [
173-
${c.yellow(c.bold(`"${name}"`))}
174-
]
172+
experimentalOptimizer: {
173+
enabled: true,
174+
include: [
175+
${c.yellow(c.bold(`"${name}"`))}
176+
]
177+
}
175178
}
176179
}
177180
}\n`)))

packages/vitest/src/node/plugins/index.ts

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { builtinModules } from 'node:module'
2+
import { version as viteVersion } from 'vite'
13
import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite'
24
import { relative } from 'pathe'
35
import { configDefaults } from '../../defaults'
@@ -134,49 +136,32 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('t
134136
}
135137

136138
const optimizeConfig: Partial<ViteConfig> = {}
137-
// TODO: optimizer is temporary disabled, until Vite provides "optimzier.byDefault" option
138-
// const optimizer = preOptions.deps?.experimentalOptimizer
139-
// if (!optimizer?.enabled) {
140-
optimizeConfig.cacheDir = undefined
141-
optimizeConfig.optimizeDeps = {
142-
// experimental in Vite >2.9.2, entries remains to help with older versions
143-
disabled: true,
144-
entries: [],
139+
const optimizer = preOptions.deps?.experimentalOptimizer
140+
const [major, minor] = viteVersion.split('.').map(Number)
141+
const allowed = major >= 5 || (major === 4 && minor >= 3)
142+
if (!allowed && optimizer?.enabled === true)
143+
console.warn(`Vitest: "deps.experimentalOptimizer" is only available in Vite >= 4.3.0, current Vite version: ${viteVersion}`)
144+
if (!allowed || optimizer?.enabled !== true) {
145+
optimizeConfig.cacheDir = undefined
146+
optimizeConfig.optimizeDeps = {
147+
// experimental in Vite >2.9.2, entries remains to help with older versions
148+
disabled: true,
149+
entries: [],
150+
}
151+
}
152+
else {
153+
const cacheDir = preOptions.cache !== false ? preOptions.cache?.dir : null
154+
optimizeConfig.cacheDir = cacheDir ?? 'node_modules/.vitest'
155+
optimizeConfig.optimizeDeps = {
156+
...viteConfig.optimizeDeps,
157+
...optimizer,
158+
noDiscovery: true,
159+
disabled: false,
160+
entries: [],
161+
exclude: ['vitest', ...builtinModules, ...(optimizer.exclude || viteConfig.optimizeDeps?.exclude || [])],
162+
include: (optimizer.include || viteConfig.optimizeDeps?.include || []).filter((n: string) => n !== 'vitest'),
163+
}
145164
}
146-
// }
147-
// else {
148-
// const root = config.root || process.cwd()
149-
// // TODO: add support for experimental optimizer
150-
// const entries = []
151-
// // const [...entries] = await ctx.globAllTestFiles(preOptions as ResolvedConfig, preOptions.dir || root)
152-
// if (preOptions?.setupFiles) {
153-
// const setupFiles = toArray(preOptions.setupFiles).map((file: string) =>
154-
// normalize(
155-
// resolveModule(file, { paths: [root] })
156-
// ?? resolve(root, file),
157-
// ),
158-
// )
159-
// entries.push(...setupFiles)
160-
// }
161-
// const cacheDir = preOptions.cache !== false ? preOptions.cache?.dir : null
162-
// optimizeConfig.cacheDir = cacheDir ?? 'node_modules/.vitest'
163-
// optimizeConfig.optimizeDeps = {
164-
// ...viteConfig.optimizeDeps,
165-
// ...optimizer,
166-
// disabled: false,
167-
// entries: [...(viteConfig.optimizeDeps?.entries || []), ...entries],
168-
// exclude: ['vitest', ...builtinModules, ...(optimizer.exclude || viteConfig.optimizeDeps?.exclude || [])],
169-
// include: (optimizer.include || viteConfig.optimizeDeps?.include || []).filter((n: string) => n !== 'vitest'),
170-
// }
171-
// // Vite throws an error that it cannot rename "deps_temp", but optimization still works
172-
// // let's not show this error to users
173-
// const { error: logError } = console
174-
// console.error = (...args) => {
175-
// if (typeof args[0] === 'string' && args[0].includes('/deps_temp'))
176-
// return
177-
// return logError(...args)
178-
// }
179-
// }
180165
Object.assign(config, optimizeConfig)
181166

182167
return config

packages/vitest/src/node/plugins/workspace.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { builtinModules } from 'node:module'
12
import { dirname, relative } from 'pathe'
23
import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite'
4+
import { version as viteVersion } from 'vite'
35
import { configDefaults } from '../../defaults'
46
import { generateScopedClassName } from '../../integrations/css/css-modules'
57
import { deepMerge } from '../../utils/base'
@@ -116,6 +118,35 @@ export function WorkspaceVitestPlugin(project: WorkspaceProject, options: Worksp
116118
}
117119
}
118120

121+
const optimizeConfig: Partial<ViteConfig> = {}
122+
const optimizer = testConfig.deps?.experimentalOptimizer
123+
const [major, minor] = viteVersion.split('.').map(Number)
124+
const allowed = major >= 5 || (major === 4 && minor >= 3)
125+
if (!allowed && optimizer?.enabled === true)
126+
console.warn(`Vitest: "deps.experimentalOptimizer" is only available in Vite >= 4.3.0, current Vite version: ${viteVersion}`)
127+
if (!allowed || optimizer?.enabled !== true) {
128+
optimizeConfig.cacheDir = undefined
129+
optimizeConfig.optimizeDeps = {
130+
// experimental in Vite >2.9.2, entries remains to help with older versions
131+
disabled: true,
132+
entries: [],
133+
}
134+
}
135+
else {
136+
const cacheDir = testConfig.cache !== false ? testConfig.cache?.dir : null
137+
optimizeConfig.cacheDir = cacheDir ?? 'node_modules/.vitest'
138+
optimizeConfig.optimizeDeps = {
139+
...viteConfig.optimizeDeps,
140+
...optimizer,
141+
noDiscovery: true,
142+
disabled: false,
143+
entries: [],
144+
exclude: ['vitest', ...builtinModules, ...(optimizer.exclude || viteConfig.optimizeDeps?.exclude || [])],
145+
include: (optimizer.include || viteConfig.optimizeDeps?.include || []).filter((n: string) => n !== 'vitest'),
146+
}
147+
}
148+
Object.assign(config, optimizeConfig)
149+
119150
return config
120151
},
121152
async configureServer(server) {

packages/vitest/src/types/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ interface DepsOptions {
7474
/**
7575
* Enable dependency optimization. This can improve the performance of your tests.
7676
*/
77-
experimentalOptimizer?: Omit<DepOptimizationConfig, 'disabled'> & {
77+
experimentalOptimizer?: Omit<DepOptimizationConfig, 'disabled' | 'noDiscovery'> & {
7878
enabled: boolean
7979
}
8080
/**

pnpm-lock.yaml

Lines changed: 6 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)