> For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt.

# extends

- **类型：** `ExtendConfig | ExtendConfigFn | (ExtendConfig | ExtendConfigFn)[]`
- **默认值：** `undefined`

`extends` 选项允许你从外部来源扩展 Rstest 配置，例如使用适配器将其他构建工具的配置转换为 Rstest 兼容格式。

这样可以实现以下功能：

- **适配器集成**：通过 `@rstest/adapter-rslib` 等适配器从其他构建工具配置中扩展 Rstest 配置
- **异步配置**：从外部源异步加载配置
- **配置合并**：自动将扩展配置与本地 Rstest 配置合并
- **可组合预设**：通过 `extends` 数组组合多个共享配置

## 基本用法（对象）

```ts
type ExtendConfig = Omit<RstestConfig, 'projects'>;
```

`ExtendConfig` 是 `RstestConfig` 子集，不包含 `projects` 字段。

你可以用它从外部源扩展 Rstest 配置。Rstest 会按[合并规则](#配置合并)将扩展配置与本地配置合并。

```ts
import { defineConfig } from '@rstest/core';
import { sharedConfig } from './shared.config';

export default defineConfig({
  extends: sharedConfig,
  // 本地配置
  testTimeout: 10000,
  retry: 2,
});
```

## 函数用法

```ts
type ExtendConfigFn = (
  userConfig: Readonly<RstestConfig>,
) => ExtendConfig | Promise<ExtendConfig>;
```

`ExtendConfigFn` 是一个接收用户配置(只读)并返回扩展配置的函数。

它适用于加载外部配置文件、获取远程配置或基于用户设置进行动态配置。

```ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  extends: async (user) => {
    const useJsdom = user.testEnvironment === 'jsdom';
    return {
      setupFiles: useJsdom ? ['<rootDir>/setupDomTests.ts'] : undefined,
      source: {
        define: {
          BUILD_TARGET: '"test" ',
        },
      },
    };
  },
  testTimeout: 10_000,
});
```

## 多个 extends

当你需要组合多个预设时，可以给 `extends` 传入数组。

Rstest 会按从左到右的顺序依次解析数组。后面的条目会覆盖前面的冲突字段，而本地配置仍然拥有最高优先级。

当数组项为函数时，每个 `ExtendConfigFn` 都会基于原始的用户配置独立解析。数组顺序只影响最终合并优先级，不会影响传给每个函数的输入。

```ts
import { defineConfig } from '@rstest/core';
import { withRslibConfig } from '@rstest/adapter-rslib';
import { sharedConfig } from './shared.config';

export default defineConfig({
  extends: [
    sharedConfig,
    withRslibConfig({}),
    (userConfig) => ({
      globals: userConfig.retry !== undefined,
    }),
  ],
  testTimeout: 10_000,
});
```

## 配置合并

Rstest 对对象配置执行深度合并，对基本类型配置执行简单覆盖。本地配置优先于扩展配置。

当 `extends` 为数组时，优先级顺序如下：

```ts
extends[0] < extends[1] < ... < extends[n] < local config
```

主要合并规则如下：

- `testTimeout`、`retry`、`globals` 这类基本类型字段由后者直接覆盖前者。
- `setupFiles`、`globalSetup` 和 `plugins` 会拼接，方便多个预设共同追加配置。
- `include`、`reporters` 和 `coverage.reporters` 会被后者整体替换。
- `source`、`resolve`、`output`、`tools`、`env` 和 `coverage` 等对象字段会执行深度合并。
- `browser` 会执行浅合并，后者的同名属性覆盖前者。
- 每个扩展配置中的 `projects` 都会被忽略。

```ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  extends: [
    {
      testEnvironment: 'jsdom',
      setupFiles: ['./setup-a.ts'],
      testTimeout: 5000,
      source: {
        define: {
          BASE_URL: '"https://example.com"',
        },
      },
    },
    {
      globals: true,
      setupFiles: ['./setup-b.ts'],
      source: {
        define: {
          API_URL: '"https://api.example.com"',
        },
      },
    },
  ],
  // 本地配置
  testTimeout: 10000,
  retry: 2,
});

// 结果：
// {
//   testEnvironment: 'jsdom',
//   globals: true,
//   testTimeout: 10000,
//   retry: 2,
//   setupFiles: ['./setup-a.ts', './setup-b.ts'],
//   source: {
//     define: {
//       BASE_URL: '"https://example.com"',
//       API_URL: '"https://api.example.com"',
//     },
//   },
// }
```

## 使用适配器

### 示例：从 Rslib 配置扩展

使用 `@rstest/adapter-rslib` 适配器可从现有 Rslib 配置文件扩展 Rstest 配置。该适配器会自动映射兼容选项，如 `source.define`、`source.include`、`source.exclude`、`source.transformImport` 等。

```ts
import { defineConfig } from '@rstest/core';
import { withRslibConfig } from '@rstest/adapter-rslib';

export default defineConfig({
  extends: withRslibConfig({}),
  // 额外的 Rstest 特定配置
  coverage: {
    enabled: true,
    reporters: ['text', 'html'],
  },
});
```

## 限制

`extends` 配置不支持 `projects` 字段。要定义多个项目，请单独扩展每个项目：

```ts
export default defineConfig({
  projects: [
    {
      extends: withRslibConfig({ libId: 'node' }),
      include: ['tests/node/**/*.{test,spec}.?(c|m)[jt]s'],
    },
    {
      extends: withRslibConfig({ libId: 'react' }),
      include: ['tests/react/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
    },
  ],
});
```
