Skip to content

Commit 798c0da

Browse files
authoredJan 14, 2025··
fix(workspace): extends: true correctly inherits all root config properties (#7232)
1 parent aec0b53 commit 798c0da

File tree

7 files changed

+52
-11
lines changed

7 files changed

+52
-11
lines changed
 

‎docs/guide/workspace.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default defineConfig({
4444
Vitest will treat every folder in `packages` as a separate project even if it doesn't have a config file inside. If this glob pattern matches any file it will be considered a Vitest config even if it doesn't have a `vitest` in its name.
4545

4646
::: warning
47-
Vitest does not treat the root `vitest.config` file as a workspace project unless it is explicitly specified in the workspace configuration. Consequently, the root configuration will only influence global options such as `reporters` and `coverage`.
47+
Vitest does not treat the root `vitest.config` file as a workspace project unless it is explicitly specified in the workspace configuration. Consequently, the root configuration will only influence global options such as `reporters` and `coverage`. Note that Vitest will always run certain plugin hooks, like `apply`, `config`, `configResolved` or `configureServer`, specified in the root config file. Vitest also uses the same plugins to execute global setups, workspace files and custom coverage provider.
4848
:::
4949

5050
You can also reference projects with their config files:
@@ -233,7 +233,7 @@ bun test --project e2e --project unit
233233

234234
## Configuration
235235

236-
None of the configuration options are inherited from the root-level config file. You can create a shared config file and merge it with the project config yourself:
236+
None of the configuration options are inherited from the root-level config file, even if the workspace is defined inside that config and not in a separate `vitest.workspace` file. You can create a shared config file and merge it with the project config yourself:
237237

238238
```ts [packages/a/vitest.config.ts]
239239
import { defineProject, mergeConfig } from 'vitest/config'

‎packages/vitest/src/node/project.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,6 @@ export interface SerializedTestProject {
717717

718718
interface InitializeProjectOptions extends UserWorkspaceConfig {
719719
configFile: string | false
720-
extends?: string
721720
}
722721

723722
export async function initializeProject(
@@ -727,7 +726,7 @@ export async function initializeProject(
727726
) {
728727
const project = new TestProject(workspacePath, ctx, options)
729728

730-
const { extends: extendsConfig, configFile, ...restOptions } = options
729+
const { configFile, ...restOptions } = options
731730

732731
const config: ViteInlineConfig = {
733732
...restOptions,

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

+4-6
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,9 @@ export async function resolveWorkspace(
6262
// if extends a config file, resolve the file path
6363
const configFile = typeof options.extends === 'string'
6464
? resolve(configRoot, options.extends)
65-
: false
66-
// if extends a root config, use the users root options
67-
const rootOptions = options.extends === true
68-
? vitest._options
69-
: {}
65+
: options.extends === true
66+
? (vitest.vite.config.configFile || false)
67+
: false
7068
// if `root` is configured, resolve it relative to the workspace file or vite root (like other options)
7169
// if `root` is not specified, inline configs use the same root as the root project
7270
const root = options.root
@@ -75,7 +73,7 @@ export async function resolveWorkspace(
7573
projectPromises.push(concurrent(() => initializeProject(
7674
index,
7775
vitest,
78-
mergeConfig(rootOptions, { ...options, root, configFile }) as any,
76+
{ ...options, root, configFile },
7977
)))
8078
})
8179

‎test/config/fixtures/workspace/browser/workspace-with-browser.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default defineWorkspace([
77
browser: {
88
enabled: true,
99
provider: 'webdriverio',
10-
name: 'chrome'
10+
name: 'chrome',
1111
},
1212
}
1313
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { test, expect } from 'vitest';
2+
import repro from 'virtual:repro';
3+
4+
test('importing a virtual module', () => {
5+
expect(repro).toBe('Hello, world!');
6+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { defineConfig } from 'vitest/config';
2+
3+
export default defineConfig({
4+
plugins: [
5+
{
6+
name: 'virtual',
7+
resolveId(source) {
8+
if (source === 'virtual:repro') {
9+
return '\0virtual:repro';
10+
}
11+
},
12+
load(id) {
13+
if (id === '\0virtual:repro') {
14+
return `export default "Hello, world!"`;
15+
}
16+
},
17+
},
18+
],
19+
test: {
20+
workspace: [
21+
{
22+
extends: true,
23+
test: {
24+
name: 'node',
25+
environment: 'node',
26+
},
27+
},
28+
],
29+
},
30+
});

‎test/config/test/workspace.test.ts

+8
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,11 @@ it('can define inline workspace config programmatically', async () => {
126126
expect(stdout).toContain('project-3')
127127
expect(stdout).toContain('3 passed')
128128
})
129+
130+
it('correctly inherits the root config', async () => {
131+
const { stderr, stdout } = await runVitest({
132+
root: 'fixtures/workspace/config-extends',
133+
})
134+
expect(stderr).toBe('')
135+
expect(stdout).toContain('repro.test.js > importing a virtual module')
136+
})

0 commit comments

Comments
 (0)
Please sign in to comment.