Skip to content

Commit 210ba00

Browse files
fix: preserve correct root during resolve config (#10909)
Co-authored-by: Vladimir Sheremet <sleuths.slews0s@icloud.com>
1 parent 67e8485 commit 210ba00

14 files changed

Lines changed: 480 additions & 64 deletions

File tree

‎packages/vitest/src/node/config/resolveConfig.ts‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,16 @@ function resolvePath(path: string, root: string) {
5656
)
5757
}
5858

59-
export function findConfigFile(root: string): string | undefined {
59+
export function findConfigFile(root: string): string | false {
6060
for (const configFile of configFiles) {
6161
const configPath = resolve(root, configFile)
6262
if (existsSync(configPath)) {
6363
return configPath
6464
}
6565
}
66+
// if not found, then there is no config to find.
67+
// `false` will stop vite from trying to find it again
68+
return false
6669
}
6770

6871
function parseInspector(inspect: string | undefined | boolean | number) {
@@ -1118,10 +1121,12 @@ export async function resolveConfig(
11181121
// We clone CLI Options and Vite overrides to reuse when a watch mode is triggered.
11191122
const cliOptionsCopy = deepMerge({}, options) as UserConfig
11201123
const viteOverridesCopy = deepMerge({}, viteOverrides) as ViteUserConfig
1121-
const root = resolve(options.root || process.cwd())
1122-
const configPath = resolveConfigPath(root, options)
1124+
const configPath = resolveConfigPath(
1125+
// try to find the config relative to `--root` or process.cwd()
1126+
resolve(options.root || process.cwd()),
1127+
options,
1128+
)
11231129
options.config = configPath
1124-
options.root = root
11251130

11261131
const captures: ConfigResolutionCaptures = {}
11271132
const inlineConfig: InlineConfig = mergeConfig(
@@ -1135,11 +1140,11 @@ export async function resolveConfig(
11351140
CaptureRawTestConfig(captures, cliOptionsCopy.sharedViteServer),
11361141
...TestConfigPlugin(pluginsHarness, captures, cliOptionsCopy),
11371142
...ViteConfigPlugin(pluginsHarness),
1138-
...VitestCorePlugin(pluginsHarness, options),
1143+
...VitestCorePlugin(pluginsHarness),
11391144
...BrowserLoaderPlugin(captures, pluginsHarness),
11401145
],
11411146
} satisfies InlineConfig,
1142-
mergeConfig(viteOverrides, { root }),
1147+
viteOverrides,
11431148
)
11441149

11451150
const rootViteConfig = await viteResolveConfig(inlineConfig, 'serve')

‎packages/vitest/src/node/plugins/config.ts‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { relative } from 'pathe'
55
import * as vite from 'vite'
66
import { generateScopedClassName } from '../../integrations/css/css-modules'
77
import { createViteLogger, silenceImportViteIgnoreWarning } from '../viteLogger'
8-
import { VitestOptimizer } from './optimizer'
98
import { ModuleRunnerTransform } from './runnerTransform'
109
import { getDefaultResolveOptions } from './utils'
1110

@@ -163,7 +162,6 @@ export function ViteConfigPlugin(harness: PluginHarness): Plugin[] {
163162
},
164163
},
165164
},
166-
VitestOptimizer(),
167165
ModuleRunnerTransform(),
168166
]
169167
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { Plugin as VitePlugin } from 'vite'
2-
import type { CliOptions } from '../cli/cli-api'
32
import type { PluginHarness } from '../config/pluginHarness'
43
import { resolve } from 'pathe'
54
import { configDefaults } from '../../defaults'
@@ -9,9 +8,10 @@ import { MetaEnvReplacerPlugin } from './metaEnvReplacer'
98
import { MocksPlugins } from './mocks'
109
import { NormalizeURLPlugin } from './normalizeURL'
1110
import { SsrRunnerFixerPlugin } from './ssrRunnerFixer'
11+
import { resolveTestCacheDir } from './utils'
1212
import { VitestCoreResolver } from './vitestResolver'
1313

14-
export function VitestCorePlugin(harness: PluginHarness, options: CliOptions = {}): VitePlugin[] {
14+
export function VitestCorePlugin(harness: PluginHarness): VitePlugin[] {
1515
return [
1616
{
1717
name: 'vitest:config:append',
@@ -22,11 +22,12 @@ export function VitestCorePlugin(harness: PluginHarness, options: CliOptions = {
2222
config: {
2323
order: 'post',
2424
handler(viteConfig) {
25-
const root = resolve(options.root || viteConfig.test?.root || viteConfig.root || process.cwd())
25+
const root = resolve(viteConfig.test?.root || viteConfig.root || process.cwd())
2626

2727
return {
2828
base: '/',
2929
root,
30+
cacheDir: resolveTestCacheDir(root, viteConfig.test || {}, viteConfig.cacheDir),
3031
build: {
3132
// Vitest doesn't use outputDir, but this value affects what folders are watched
3233
// https://github.com/vitejs/vite/pull/16453

‎packages/vitest/src/node/plugins/optimizer.ts‎

Lines changed: 0 additions & 27 deletions
This file was deleted.

‎packages/vitest/src/node/plugins/testConfig.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import { escapeRegExp } from '../../utils/base'
1717
import { resolveApiServerConfig } from '../config/resolveConfig'
1818
import { deleteDefineConfig } from './utils'
1919

20-
// `name` must stay unique per project, `projects` would redefine the whole workspace
21-
const NON_INHERITED_OPTIONS = ['name', 'projects'] as const
20+
// `name` must stay unique per project, `projects` would redefine the whole
21+
// workspace, and `root` would re-root the project onto the declaring config
22+
const NON_INHERITED_OPTIONS = ['name', 'projects', 'root'] as const
2223

2324
// the root `globalSetup` already runs once per test run; a non-root
2425
// config (a shared config or a container) keeps it because nothing else runs it

‎packages/vitest/src/node/plugins/utils.ts‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,28 @@ import type {
22
DepOptimizationOptions,
33
UserConfig as ViteConfig,
44
} from 'vite'
5-
import type { DepsOptimizationOptions } from '../types/config'
5+
import type { DepsOptimizationOptions, UserConfig } from '../types/config'
66
import { dirname } from 'pathe'
77
import { searchForWorkspaceRoot, version as viteVersion } from 'vite'
88
import * as vite from 'vite'
99
import { rootDir } from '../../paths'
10+
import { VitestCache } from '../cache'
11+
12+
export function resolveTestCacheDir(
13+
root: string,
14+
testConfig: UserConfig,
15+
viteCacheDir: string | undefined,
16+
): string {
17+
const name = testConfig.name
18+
const label = typeof name === 'string' ? name : (name?.label || '')
19+
return VitestCache.resolveCacheDir(
20+
root,
21+
testConfig.cache != null && testConfig.cache !== false
22+
? testConfig.cache.dir
23+
: viteCacheDir,
24+
label,
25+
)
26+
}
1027

1128
export function resolveOptimizerConfig(
1229
testOptions_: DepsOptimizationOptions | undefined,

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type * as vite from 'vite'
22
import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite'
33
import type { PluginHarness } from '../config/pluginHarness'
4-
import type { ResolvedConfig, TestProjectInlineConfiguration } from '../types/config'
4+
import { resolve } from 'pathe'
55
import { API_TOKEN_FILE } from '../config/apiToken'
66
import { ViteConfigPlugin } from './config'
77
import { CoverageTransform } from './coverageTransform'
@@ -10,17 +10,12 @@ import { MetaEnvReplacerPlugin } from './metaEnvReplacer'
1010
import { MocksPlugins } from './mocks'
1111
import { NormalizeURLPlugin } from './normalizeURL'
1212
import { SsrRunnerFixerPlugin } from './ssrRunnerFixer'
13+
import { resolveTestCacheDir } from './utils'
1314
import { VitestProjectResolver } from './vitestResolver'
1415

15-
interface WorkspaceOptions extends TestProjectInlineConfiguration {
16-
root?: string
17-
}
18-
1916
export function WorkspaceVitestPlugin(
2017
harness: PluginHarness,
2118
globalViteConfig: vite.ResolvedConfig,
22-
globalConfig: ResolvedConfig,
23-
options: WorkspaceOptions,
2419
): VitePlugin[] {
2520
return [
2621
{
@@ -31,11 +26,16 @@ export function WorkspaceVitestPlugin(
3126
},
3227
config(viteConfig) {
3328
const testConfig = viteConfig.test || {}
34-
const root = options.root || testConfig.root || viteConfig.root
29+
const root = testConfig.root || viteConfig.root
3530

3631
const config: ViteConfig = {
3732
base: '/',
3833
root,
34+
cacheDir: resolveTestCacheDir(
35+
resolve(root || process.cwd()),
36+
testConfig,
37+
viteConfig.cacheDir,
38+
),
3939
server: {
4040
open: false,
4141
fs: {

‎packages/vitest/src/node/projects/resolveProjects.ts‎

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,16 +329,17 @@ async function resolveDeclaredProjectEntries(
329329
: options.extends !== false
330330
? (parentViteConfig.configFile || false)
331331
: false
332-
// if `root` is configured, resolve it relative to the declaring config's
333-
// root (like other options); if `root` is not specified, inline configs
334-
// use the same root as the declaring config
335-
const rawRoot = options.test?.root ?? options.root
336-
const root = rawRoot
337-
? resolve(configRoot, rawRoot)
338-
: configRoot
332+
// `test.root` overrides the top level `root`, so the entry carries a
333+
// single resolved root; both are resolved relative to the declaring
334+
// config's root (like other options), and inline configs without a
335+
// root use the same root as the declaring config
336+
const { root: testRoot, ...test } = options.test ?? {}
337+
const customRoot = testRoot ?? options.root
338+
const root = customRoot ? resolve(configRoot, customRoot) : configRoot
339339

340340
promises.push(concurrent(() => resolveSingleProjectEntry(context, {
341341
...options,
342+
test,
342343
root,
343344
configFile,
344345
}, index)))
@@ -733,12 +734,7 @@ async function resolveSingleProjectEntry(
733734
isInlineEntry ? { options, extendsTrueRootConfig } : undefined,
734735
),
735736
...(options.plugins || []),
736-
...WorkspaceVitestPlugin(
737-
harness,
738-
parentViteConfig,
739-
rootConfig,
740-
options,
741-
),
737+
...WorkspaceVitestPlugin(harness, parentViteConfig),
742738
...BrowserLoaderPlugin(captures, harness),
743739
],
744740
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { expect, test } from 'vitest'
2+
3+
test('example test', () => {
4+
expect(1 + 1).toBe(2)
5+
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function setup() {
2+
// File should load without errors
3+
}

0 commit comments

Comments
 (0)