Skip to content

Commit

Permalink
feat: enable experimentalOptimizer (#3413)
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va authored Jun 1, 2023
1 parent 0caadf4 commit 5a894aa
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 54 deletions.
7 changes: 2 additions & 5 deletions docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,16 @@ Handling for dependencies resolution.
- **Version:** Since Vitest 0.29.0
- **See also:** [Dep Optimization Options](https://vitejs.dev/config/dep-optimization-options.html)

::: warning
This feature is temporarily disabled since Vitest 0.30.0.
:::

Enable dependency optimization. If you have a lot of tests, this might improve their performance.

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:

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

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.
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.

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.

Expand Down
9 changes: 6 additions & 3 deletions packages/vitest/src/node/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,12 @@ function printModuleWarningForPackage(logger: Logger, path: string, name: string
+ c.green(`export default {
test: {
deps: {
inline: [
${c.yellow(c.bold(`"${name}"`))}
]
experimentalOptimizer: {
enabled: true,
include: [
${c.yellow(c.bold(`"${name}"`))}
]
}
}
}
}\n`)))
Expand Down
69 changes: 27 additions & 42 deletions packages/vitest/src/node/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { builtinModules } from 'node:module'
import { version as viteVersion } from 'vite'
import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite'
import { relative } from 'pathe'
import { configDefaults } from '../../defaults'
Expand Down Expand Up @@ -134,49 +136,32 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('t
}

const optimizeConfig: Partial<ViteConfig> = {}
// TODO: optimizer is temporary disabled, until Vite provides "optimzier.byDefault" option
// const optimizer = preOptions.deps?.experimentalOptimizer
// if (!optimizer?.enabled) {
optimizeConfig.cacheDir = undefined
optimizeConfig.optimizeDeps = {
// experimental in Vite >2.9.2, entries remains to help with older versions
disabled: true,
entries: [],
const optimizer = preOptions.deps?.experimentalOptimizer
const [major, minor] = viteVersion.split('.').map(Number)
const allowed = major >= 5 || (major === 4 && minor >= 3)
if (!allowed && optimizer?.enabled === true)
console.warn(`Vitest: "deps.experimentalOptimizer" is only available in Vite >= 4.3.0, current Vite version: ${viteVersion}`)
if (!allowed || optimizer?.enabled !== true) {
optimizeConfig.cacheDir = undefined
optimizeConfig.optimizeDeps = {
// experimental in Vite >2.9.2, entries remains to help with older versions
disabled: true,
entries: [],
}
}
else {
const cacheDir = preOptions.cache !== false ? preOptions.cache?.dir : null
optimizeConfig.cacheDir = cacheDir ?? 'node_modules/.vitest'
optimizeConfig.optimizeDeps = {
...viteConfig.optimizeDeps,
...optimizer,
noDiscovery: true,
disabled: false,
entries: [],
exclude: ['vitest', ...builtinModules, ...(optimizer.exclude || viteConfig.optimizeDeps?.exclude || [])],
include: (optimizer.include || viteConfig.optimizeDeps?.include || []).filter((n: string) => n !== 'vitest'),
}
}
// }
// else {
// const root = config.root || process.cwd()
// // TODO: add support for experimental optimizer
// const entries = []
// // const [...entries] = await ctx.globAllTestFiles(preOptions as ResolvedConfig, preOptions.dir || root)
// if (preOptions?.setupFiles) {
// const setupFiles = toArray(preOptions.setupFiles).map((file: string) =>
// normalize(
// resolveModule(file, { paths: [root] })
// ?? resolve(root, file),
// ),
// )
// entries.push(...setupFiles)
// }
// const cacheDir = preOptions.cache !== false ? preOptions.cache?.dir : null
// optimizeConfig.cacheDir = cacheDir ?? 'node_modules/.vitest'
// optimizeConfig.optimizeDeps = {
// ...viteConfig.optimizeDeps,
// ...optimizer,
// disabled: false,
// entries: [...(viteConfig.optimizeDeps?.entries || []), ...entries],
// exclude: ['vitest', ...builtinModules, ...(optimizer.exclude || viteConfig.optimizeDeps?.exclude || [])],
// include: (optimizer.include || viteConfig.optimizeDeps?.include || []).filter((n: string) => n !== 'vitest'),
// }
// // Vite throws an error that it cannot rename "deps_temp", but optimization still works
// // let's not show this error to users
// const { error: logError } = console
// console.error = (...args) => {
// if (typeof args[0] === 'string' && args[0].includes('/deps_temp'))
// return
// return logError(...args)
// }
// }
Object.assign(config, optimizeConfig)

return config
Expand Down
31 changes: 31 additions & 0 deletions packages/vitest/src/node/plugins/workspace.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { builtinModules } from 'node:module'
import { dirname, relative } from 'pathe'
import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite'
import { version as viteVersion } from 'vite'
import { configDefaults } from '../../defaults'
import { generateScopedClassName } from '../../integrations/css/css-modules'
import { deepMerge } from '../../utils/base'
Expand Down Expand Up @@ -116,6 +118,35 @@ export function WorkspaceVitestPlugin(project: WorkspaceProject, options: Worksp
}
}

const optimizeConfig: Partial<ViteConfig> = {}
const optimizer = testConfig.deps?.experimentalOptimizer
const [major, minor] = viteVersion.split('.').map(Number)
const allowed = major >= 5 || (major === 4 && minor >= 3)
if (!allowed && optimizer?.enabled === true)
console.warn(`Vitest: "deps.experimentalOptimizer" is only available in Vite >= 4.3.0, current Vite version: ${viteVersion}`)
if (!allowed || optimizer?.enabled !== true) {
optimizeConfig.cacheDir = undefined
optimizeConfig.optimizeDeps = {
// experimental in Vite >2.9.2, entries remains to help with older versions
disabled: true,
entries: [],
}
}
else {
const cacheDir = testConfig.cache !== false ? testConfig.cache?.dir : null
optimizeConfig.cacheDir = cacheDir ?? 'node_modules/.vitest'
optimizeConfig.optimizeDeps = {
...viteConfig.optimizeDeps,
...optimizer,
noDiscovery: true,
disabled: false,
entries: [],
exclude: ['vitest', ...builtinModules, ...(optimizer.exclude || viteConfig.optimizeDeps?.exclude || [])],
include: (optimizer.include || viteConfig.optimizeDeps?.include || []).filter((n: string) => n !== 'vitest'),
}
}
Object.assign(config, optimizeConfig)

return config
},
async configureServer(server) {
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ interface DepsOptions {
/**
* Enable dependency optimization. This can improve the performance of your tests.
*/
experimentalOptimizer?: Omit<DepOptimizationConfig, 'disabled'> & {
experimentalOptimizer?: Omit<DepOptimizationConfig, 'disabled' | 'noDiscovery'> & {
enabled: boolean
}
/**
Expand Down
9 changes: 6 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5a894aa

Please sign in to comment.