Skip to content

Commit

Permalink
fix(workspace): extends: true correctly inherits all root config pr…
Browse files Browse the repository at this point in the history
…operties (#7232)
  • Loading branch information
sheremet-va authored Jan 14, 2025
1 parent aec0b53 commit 798c0da
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 11 deletions.
4 changes: 2 additions & 2 deletions docs/guide/workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default defineConfig({
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.

::: warning
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`.
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.
:::

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

## Configuration

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

```ts [packages/a/vitest.config.ts]
import { defineProject, mergeConfig } from 'vitest/config'
Expand Down
3 changes: 1 addition & 2 deletions packages/vitest/src/node/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,6 @@ export interface SerializedTestProject {

interface InitializeProjectOptions extends UserWorkspaceConfig {
configFile: string | false
extends?: string
}

export async function initializeProject(
Expand All @@ -727,7 +726,7 @@ export async function initializeProject(
) {
const project = new TestProject(workspacePath, ctx, options)

const { extends: extendsConfig, configFile, ...restOptions } = options
const { configFile, ...restOptions } = options

const config: ViteInlineConfig = {
...restOptions,
Expand Down
10 changes: 4 additions & 6 deletions packages/vitest/src/node/workspace/resolveWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,9 @@ export async function resolveWorkspace(
// if extends a config file, resolve the file path
const configFile = typeof options.extends === 'string'
? resolve(configRoot, options.extends)
: false
// if extends a root config, use the users root options
const rootOptions = options.extends === true
? vitest._options
: {}
: options.extends === true
? (vitest.vite.config.configFile || false)
: false
// if `root` is configured, resolve it relative to the workspace file or vite root (like other options)
// if `root` is not specified, inline configs use the same root as the root project
const root = options.root
Expand All @@ -75,7 +73,7 @@ export async function resolveWorkspace(
projectPromises.push(concurrent(() => initializeProject(
index,
vitest,
mergeConfig(rootOptions, { ...options, root, configFile }) as any,
{ ...options, root, configFile },
)))
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default defineWorkspace([
browser: {
enabled: true,
provider: 'webdriverio',
name: 'chrome'
name: 'chrome',
},
}
}
Expand Down
6 changes: 6 additions & 0 deletions test/config/fixtures/workspace/config-extends/repro.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { test, expect } from 'vitest';
import repro from 'virtual:repro';

test('importing a virtual module', () => {
expect(repro).toBe('Hello, world!');
});
30 changes: 30 additions & 0 deletions test/config/fixtures/workspace/config-extends/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
plugins: [
{
name: 'virtual',
resolveId(source) {
if (source === 'virtual:repro') {
return '\0virtual:repro';
}
},
load(id) {
if (id === '\0virtual:repro') {
return `export default "Hello, world!"`;
}
},
},
],
test: {
workspace: [
{
extends: true,
test: {
name: 'node',
environment: 'node',
},
},
],
},
});
8 changes: 8 additions & 0 deletions test/config/test/workspace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,11 @@ it('can define inline workspace config programmatically', async () => {
expect(stdout).toContain('project-3')
expect(stdout).toContain('3 passed')
})

it('correctly inherits the root config', async () => {
const { stderr, stdout } = await runVitest({
root: 'fixtures/workspace/config-extends',
})
expect(stderr).toBe('')
expect(stdout).toContain('repro.test.js > importing a virtual module')
})

0 comments on commit 798c0da

Please sign in to comment.