Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(vitest): correctly resolve optimizer status #3992

Merged
merged 6 commits into from Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/config/index.md
Expand Up @@ -207,10 +207,14 @@ You will not be able to edit your `node_modules` code for debugging, since the c
#### deps.optimizer.{mode}.enabled

- **Type:** `boolean`
- **Default:** `true`
- **Default:** `true` if using >= Vite 4.3.2, `false` otherwise

Enable dependency optimization.

::: warning
This option only works with Vite 4.3.2 and higher.
:::

#### deps.web

- **Type:** `{ transformAssets?, ... }`
Expand All @@ -227,7 +231,7 @@ Usually, files inside `node_modules` are externalized, but these options also af

Should Vitest process assets (.png, .svg, .jpg, etc) files and resolve them like Vite does in the browser.

hese module will have a default export equal to the path to the asset, if no query is specified.
This module will have a default export equal to the path to the asset, if no query is specified.

::: warning
At the moment, this option only works with [`experimentalVmThreads`](#experimentalvmthreads) pool.
Expand All @@ -240,7 +244,7 @@ At the moment, this option only works with [`experimentalVmThreads`](#experiment

Should Vitest process CSS (.css, .scss, .sass, etc) files and resolve them like Vite does in the browser.

If CSS files are disabled with [`css`](#css) options, this option will just silence `UNKNOWN_EXTENSION` errors.
If CSS files are disabled with [`css`](#css) options, this option will just silence `ERR_UNKNOWN_FILE_EXTENSION` errors.

::: warning
At the moment, this option only works with [`experimentalVmThreads`](#experimentalvmthreads) pool.
Expand Down
6 changes: 6 additions & 0 deletions packages/vitest/src/node/config.ts
Expand Up @@ -137,6 +137,12 @@ export function resolveConfig(
if (!resolved.deps.moduleDirectories.includes('/node_modules/'))
resolved.deps.moduleDirectories.push('/node_modules/')

resolved.deps.optimizer ??= {}
resolved.deps.optimizer.ssr ??= {}
resolved.deps.optimizer.ssr.enabled ??= true
resolved.deps.optimizer.web ??= {}
resolved.deps.optimizer.web.enabled ??= true

resolved.deps.web ??= {}
resolved.deps.web.transformAssets ??= true
resolved.deps.web.transformCss ??= true
Expand Down
13 changes: 3 additions & 10 deletions packages/vitest/src/node/plugins/index.ts
Expand Up @@ -12,8 +12,9 @@ import { GlobalSetupPlugin } from './globalSetup'
import { CSSEnablerPlugin } from './cssEnabler'
import { CoverageTransform } from './coverageTransform'
import { MocksPlugin } from './mocks'
import { deleteDefineConfig, hijackVitePluginInject, resolveFsAllow, resolveOptimizerConfig } from './utils'
import { deleteDefineConfig, hijackVitePluginInject, resolveFsAllow } from './utils'
import { VitestResolver } from './vitestResolver'
import { VitestOptimizer } from './optimizer'

export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('test')): Promise<VitePlugin[]> {
const userConfig = deepMerge({}, options) as UserConfig
Expand Down Expand Up @@ -112,15 +113,6 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('t
}
}

const webOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.web, viteConfig.optimizeDeps, testConfig)
const ssrOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.ssr, viteConfig.ssr?.optimizeDeps, testConfig)

config.cacheDir = webOptimizer.cacheDir || ssrOptimizer.cacheDir || config.cacheDir
config.optimizeDeps = webOptimizer.optimizeDeps
config.ssr = {
optimizeDeps: ssrOptimizer.optimizeDeps,
}

return config
},
async configResolved(viteConfig) {
Expand Down Expand Up @@ -195,6 +187,7 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('t
: null,
MocksPlugin(),
VitestResolver(ctx),
VitestOptimizer(),
]
.filter(notNullish)
}
22 changes: 22 additions & 0 deletions packages/vitest/src/node/plugins/optimizer.ts
@@ -0,0 +1,22 @@
import type { Plugin } from 'vite'
import { resolveOptimizerConfig } from './utils'

export function VitestOptimizer(): Plugin {
return {
name: 'vitest:normalize-optimizer',
config: {
order: 'post',
handler(viteConfig) {
const testConfig = viteConfig.test || {}
const webOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.web, viteConfig.optimizeDeps, testConfig)
const ssrOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.ssr, viteConfig.ssr?.optimizeDeps, testConfig)

viteConfig.cacheDir = webOptimizer.cacheDir || ssrOptimizer.cacheDir || viteConfig.cacheDir
viteConfig.optimizeDeps = webOptimizer.optimizeDeps
viteConfig.ssr = {
optimizeDeps: ssrOptimizer.optimizeDeps,
}
},
},
}
}
22 changes: 16 additions & 6 deletions packages/vitest/src/node/plugins/utils.ts
@@ -1,4 +1,3 @@
import { builtinModules } from 'node:module'
import { searchForWorkspaceRoot, version as viteVersion } from 'vite'
import type { DepOptimizationOptions, ResolvedConfig, UserConfig as ViteConfig } from 'vite'
import { dirname } from 'pathe'
Expand All @@ -7,10 +6,10 @@ import type { DepsOptimizationOptions, InlineConfig } from '../../types'
export function resolveOptimizerConfig(_testOptions: DepsOptimizationOptions | undefined, viteOptions: DepOptimizationOptions | undefined, testConfig: InlineConfig) {
const testOptions = _testOptions || {}
const newConfig: { cacheDir?: string; optimizeDeps: DepOptimizationOptions } = {} as any
const [major, minor] = viteVersion.split('.').map(Number)
const allowed = major >= 5 || (major === 4 && minor >= 3)
const [major, minor, fix] = viteVersion.split('.').map(Number)
const allowed = major >= 5 || (major === 4 && minor >= 4) || (major === 4 && minor === 3 && fix >= 2)
if (!allowed && testOptions?.enabled === true)
console.warn(`Vitest: "deps.optimizer" is only available in Vite >= 4.3.0, current Vite version: ${viteVersion}`)
console.warn(`Vitest: "deps.optimizer" is only available in Vite >= 4.3.2, current Vite version: ${viteVersion}`)
else
// enable by default
testOptions.enabled ??= true
Expand All @@ -24,15 +23,26 @@ export function resolveOptimizerConfig(_testOptions: DepsOptimizationOptions | u
}
else {
const cacheDir = testConfig.cache !== false ? testConfig.cache?.dir : null
const currentInclude = (testOptions.include || viteOptions?.include || [])
const exclude = [
'vitest',
// Ideally, we shouldn't optimize react in test mode, otherwise we need to optimize _every_ dependency that uses react.
'react',
...(testOptions.exclude || viteOptions?.exclude || []),
]
const runtime = currentInclude.filter(n => n.endsWith('jsx-dev-runtime'))
exclude.push(...runtime)

const include = (testOptions.include || viteOptions?.include || []).filter((n: string) => !exclude.includes(n))
newConfig.cacheDir = cacheDir ?? 'node_modules/.vitest'
newConfig.optimizeDeps = {
...viteOptions,
...testOptions,
noDiscovery: true,
disabled: false,
entries: [],
exclude: ['vitest', ...builtinModules, ...(testOptions.exclude || viteOptions?.exclude || [])],
include: (testOptions.include || viteOptions?.include || []).filter((n: string) => n !== 'vitest'),
exclude,
include,
}
}
return newConfig
Expand Down
13 changes: 3 additions & 10 deletions packages/vitest/src/node/plugins/workspace.ts
Expand Up @@ -10,8 +10,9 @@ import { CSSEnablerPlugin } from './cssEnabler'
import { SsrReplacerPlugin } from './ssrReplacer'
import { GlobalSetupPlugin } from './globalSetup'
import { MocksPlugin } from './mocks'
import { deleteDefineConfig, hijackVitePluginInject, resolveFsAllow, resolveOptimizerConfig } from './utils'
import { deleteDefineConfig, hijackVitePluginInject, resolveFsAllow } from './utils'
import { VitestResolver } from './vitestResolver'
import { VitestOptimizer } from './optimizer'

interface WorkspaceOptions extends UserWorkspaceConfig {
root?: string
Expand Down Expand Up @@ -95,15 +96,6 @@ export function WorkspaceVitestPlugin(project: WorkspaceProject, options: Worksp
}
}

const webOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.web, viteConfig.optimizeDeps, testConfig)
const ssrOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.ssr, viteConfig.ssr?.optimizeDeps, testConfig)

config.cacheDir = webOptimizer.cacheDir || ssrOptimizer.cacheDir || config.cacheDir
config.optimizeDeps = webOptimizer.optimizeDeps
config.ssr = {
optimizeDeps: ssrOptimizer.optimizeDeps,
}

return config
},
configResolved(viteConfig) {
Expand Down Expand Up @@ -132,5 +124,6 @@ export function WorkspaceVitestPlugin(project: WorkspaceProject, options: Worksp
GlobalSetupPlugin(project, project.ctx.logger),
MocksPlugin(),
VitestResolver(project.ctx),
VitestOptimizer(),
]
}
6 changes: 4 additions & 2 deletions packages/vitest/src/node/workspace.ts
Expand Up @@ -285,6 +285,7 @@ export class WorkspaceProject {
}

getSerializableConfig() {
const optimizer = this.config.deps?.optimizer
return deepMerge({
...this.config,
coverage: this.ctx.config.coverage,
Expand All @@ -293,10 +294,10 @@ export class WorkspaceProject {
...this.config.deps,
optimizer: {
web: {
enabled: this.config.deps?.optimizer?.web?.enabled ?? true,
enabled: optimizer?.web?.enabled ?? true,
},
ssr: {
enabled: this.config.deps?.optimizer?.ssr?.enabled ?? true,
enabled: optimizer?.ssr?.enabled ?? true,
},
},
},
Expand All @@ -315,6 +316,7 @@ export class WorkspaceProject {
},
inspect: this.ctx.config.inspect,
inspectBrk: this.ctx.config.inspectBrk,
alias: [],
}, this.ctx.configOverride || {} as any,
) as ResolvedConfig
}
Expand Down