From d6aca40044aee1dbb1c9a7c2362c8f391ba7afb4 Mon Sep 17 00:00:00 2001 From: 9aoy <9aoyuao@gmail.com> Date: Mon, 5 Jan 2026 19:28:54 +0800 Subject: [PATCH 1/6] feat: adapter-rsbuild --- examples/react/package.json | 3 +- examples/react/rstest.config.ts | 5 +- packages/adapter-rsbuild/README.md | 151 ++++++++++++++++++ packages/adapter-rsbuild/package.json | 49 ++++++ packages/adapter-rsbuild/rslib.config.mts | 15 ++ packages/adapter-rsbuild/rstest.config.ts | 5 + packages/adapter-rsbuild/src/index.ts | 105 ++++++++++++ packages/adapter-rsbuild/tests/index.test.ts | 105 ++++++++++++ packages/adapter-rsbuild/tsconfig.json | 11 ++ pnpm-lock.yaml | 24 ++- website/docs/en/guide/integration/_meta.json | 2 +- .../docs/en/guide/integration/adapters.mdx | 1 + website/docs/en/guide/integration/rsbuild.mdx | 101 ++++++++++++ website/docs/zh/guide/integration/_meta.json | 2 +- .../docs/zh/guide/integration/adapters.mdx | 1 + website/docs/zh/guide/integration/rsbuild.mdx | 101 ++++++++++++ 16 files changed, 672 insertions(+), 9 deletions(-) create mode 100644 packages/adapter-rsbuild/README.md create mode 100644 packages/adapter-rsbuild/package.json create mode 100644 packages/adapter-rsbuild/rslib.config.mts create mode 100644 packages/adapter-rsbuild/rstest.config.ts create mode 100644 packages/adapter-rsbuild/src/index.ts create mode 100644 packages/adapter-rsbuild/tests/index.test.ts create mode 100644 packages/adapter-rsbuild/tsconfig.json create mode 100644 website/docs/en/guide/integration/rsbuild.mdx create mode 100644 website/docs/zh/guide/integration/rsbuild.mdx diff --git a/examples/react/package.json b/examples/react/package.json index 418f0aff4..e077a4761 100644 --- a/examples/react/package.json +++ b/examples/react/package.json @@ -15,12 +15,13 @@ "devDependencies": { "@rsbuild/core": "1.7.1", "@rsbuild/plugin-react": "^1.4.2", + "@rstest/adapter-rsbuild": "workspace:*", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.1", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", - "jsdom": "^26.1.0", + "happy-dom": "^20.0.11", "typescript": "^5.9.3" } } diff --git a/examples/react/rstest.config.ts b/examples/react/rstest.config.ts index f3cef6dc5..c7439e502 100644 --- a/examples/react/rstest.config.ts +++ b/examples/react/rstest.config.ts @@ -1,8 +1,7 @@ -import { pluginReact } from '@rsbuild/plugin-react'; +import { withRsbuildConfig } from '@rstest/adapter-rsbuild'; import { defineConfig } from '@rstest/core'; export default defineConfig({ - plugins: [pluginReact()], - testEnvironment: 'jsdom', + extends: withRsbuildConfig(), setupFiles: ['./rstest.setup.ts'], }); diff --git a/packages/adapter-rsbuild/README.md b/packages/adapter-rsbuild/README.md new file mode 100644 index 000000000..5484fa7a8 --- /dev/null +++ b/packages/adapter-rsbuild/README.md @@ -0,0 +1,151 @@ +# @rstest/adapter-rsbuild + +Rstest adapter for [Rsbuild](https://rsbuild.dev) configuration. This package allows you to extend your Rstest configuration from Rsbuild config files. + +## Installation + +```bash +npm install @rstest/adapter-rsbuild -D +``` + +## Usage + +```ts +import { defineConfig } from '@rstest/core'; +import { withRsbuildConfig } from '@rstest/adapter-rsbuild'; + +export default defineConfig({ + extends: withRsbuildConfig(), + // other rstest config options +}); +``` + +## API + +### withRsbuildConfig(options) + +Returns a configuration function that loads Rsbuild config and converts it to Rstest configuration. + +#### Options + +- `cwd` (string): `cwd` passed to loadConfig of Rsbuild. Default: `process.cwd()` +- `configPath` (string): Path to rsbuild config file. Default: `'./rsbuild.config.ts'` +- `environmentName` (string): The environment name in `environments` field to use, will be merged with the common config. Set to a string to use the environment config with matching name. Default: `undefined` +- `modifyRsbuildConfig` (function): Modify rsbuild config before converting to rstest config. Default: `undefined` + +The adapter automatically copies and maps compatible configuration options from Rsbuild to Rstest: + +**From Rsbuild → to Rstest:** + +The adapter automatically maps these Rsbuild options to Rstest: + +| Rsbuild option | Rstest equivalent | Notes | +| ----------------------- | --------------------- | ------------------------------------ | +| `name` from environment | `name` | Environment identifier | +| `plugins` | `plugins` | Plugin configuration | +| `source.decorators` | `source.decorators` | Decorator support | +| `source.define` | `source.define` | Global constants | +| `source.include` | `source.include` | Source inclusion patterns | +| `source.exclude` | `source.exclude` | Source exclusion patterns | +| `source.tsconfigPath` | `source.tsconfigPath` | TypeScript config path | +| `resolve` | `resolve` | Module resolution | +| `output.cssModules` | `output.cssModules` | CSS modules configuration | +| `tools.rspack` | `tools.rspack` | Rspack configuration | +| `tools.swc` | `tools.swc` | SWC configuration | +| `tools.bundlerChain` | `tools.bundlerChain` | Bundler chain configuration | +| `output.target` | `testEnvironment` | 'happy-dom' for web, 'node' for node | + +## Advanced usage + +### Specifying working directory + +By default, the adapter uses `process.cwd()` as the working directory to resolve the Rsbuild config file. + +When your Rsbuild config is in a different directory or you are running tests in a monorepo (which your `process.cwd()` is not your config directory), you can specify the `cwd` option to resolve the Rsbuild config file from a different directory. + +```ts +export default defineConfig({ + extends: withRsbuildConfig({ + cwd: './packages/my-app', + }), +}); +``` + +### Using specific environment configuration + +By default, the adapter uses the common configuration from Rsbuild. + +If your Rsbuild config has multiple environment configurations: + +```ts +// rsbuild.config.ts +export default { + source: { + define: { + 'process.env.NODE_ENV': '"development"', + }, + }, + environments: { + test: { + source: { + define: { + 'process.env.NODE_ENV': '"test"', + }, + }, + }, + prod: { + source: { + define: { + 'process.env.NODE_ENV': '"production"', + }, + }, + }, + }, +}; +``` + +You can then reference specific environment configurations in your Rstest config. Rstest will adapt the Rsbuild shared configuration and the environment configuration with a matching `environmentName` to Rstest format. + +```ts +// For testing the 'test' environment +export default defineConfig({ + extends: withRsbuildConfig({ + environmentName: 'test', + }), + // test-environment-specific config +}); +``` + +### Multiple environment configurations + +When you need to test multiple parts of your application with different configurations independently, you can define multiple Rstest projects. Each project can extend a specific environment configuration by setting the `environmentName` option. + +```ts +export default defineConfig({ + projects: [ + { + extends: withRsbuildConfig({ environmentName: 'node' }), + include: ['tests/node/**/*.{test,spec}.?(c|m)[jt]s'], + }, + { + extends: withRsbuildConfig({ environmentName: 'react' }), + include: ['tests/react/**/*.{test,spec}.?(c|m)[jt]s?(x)'], + }, + ], +}); +``` + +### Modifying Rsbuild config + +You can modify the Rsbuild config before it gets converted to Rstest config: + +```ts +export default defineConfig({ + extends: withRsbuildConfig({ + modifyRsbuildConfig: (rsbuildConfig) => { + delete rsbuildConfig.source?.define; + return rsbuildConfig; + }, + }), +}); +``` diff --git a/packages/adapter-rsbuild/package.json b/packages/adapter-rsbuild/package.json new file mode 100644 index 000000000..8da704046 --- /dev/null +++ b/packages/adapter-rsbuild/package.json @@ -0,0 +1,49 @@ +{ + "name": "@rstest/adapter-rsbuild", + "version": "0.1.0", + "description": "Rstest adapter for rsbuild configuration", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "rslib build", + "dev": "rslib build --watch", + "test": "rstest" + }, + "keywords": [ + "rstest", + "rsbuild", + "adapter", + "configuration" + ], + "license": "MIT", + "peerDependencies": { + "@rsbuild/core": "*" + }, + "devDependencies": { + "@rslib/core": "^0.19.0", + "@rsbuild/core": "^1.7.1", + "@rstest/core": "workspace:*", + "@rstest/tsconfig": "workspace:*" + }, + "publishConfig": { + "access": "public" + }, + "bugs": { + "url": "https://github.com/web-infra-dev/rstest/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/web-infra-dev/rstest", + "directory": "packages/adapter-rsbuild" + } +} diff --git a/packages/adapter-rsbuild/rslib.config.mts b/packages/adapter-rsbuild/rslib.config.mts new file mode 100644 index 000000000..b3c44f0e6 --- /dev/null +++ b/packages/adapter-rsbuild/rslib.config.mts @@ -0,0 +1,15 @@ +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [ + { + format: 'esm', + dts: true, + bundle: true, + syntax: ['node 18.12.0'], + experiments: { + advancedEsm: true, + }, + }, + ], +}); diff --git a/packages/adapter-rsbuild/rstest.config.ts b/packages/adapter-rsbuild/rstest.config.ts new file mode 100644 index 000000000..af9f402ec --- /dev/null +++ b/packages/adapter-rsbuild/rstest.config.ts @@ -0,0 +1,5 @@ +import { defineConfig } from '@rstest/core'; + +export default defineConfig({ + root: __dirname, +}); diff --git a/packages/adapter-rsbuild/src/index.ts b/packages/adapter-rsbuild/src/index.ts new file mode 100644 index 000000000..6df3a9d3e --- /dev/null +++ b/packages/adapter-rsbuild/src/index.ts @@ -0,0 +1,105 @@ +import { + loadConfig, + mergeRsbuildConfig, + type RsbuildConfig, +} from '@rsbuild/core'; +import type { ExtendConfig, ExtendConfigFn } from '@rstest/core'; + +export interface WithRsbuildConfigOptions { + /** + * `cwd` passed to loadConfig of Rsbuild + * @default process.cwd() + */ + cwd?: string; + /** + * Path to rsbuild config file + * @default './rsbuild.config.ts' + */ + configPath?: string; + /** + * The environment name in `environments` field to use, will be merged with the common config. + * Set to a string to use the environment config with matching name. + * @default undefined + */ + environmentName?: string; + /** + * Modify rsbuild config before converting to rstest config + */ + modifyRsbuildConfig?: (buildConfig: RsbuildConfig) => RsbuildConfig; +} + +export function withRsbuildConfig( + options: WithRsbuildConfigOptions = {}, +): ExtendConfigFn { + return async () => { + const { + configPath, + modifyRsbuildConfig, + environmentName, + cwd = process.cwd(), + } = options; + + // Load rsbuild config + const { + content: { environments, ...rawBuildConfig }, + filePath, + } = await loadConfig({ + cwd, + path: configPath, + }); + + if (!filePath) { + return {}; + } + + const environmentConfig = environmentName + ? environments?.[environmentName] + : undefined; + + const rsbuildConfig = environmentConfig + ? mergeRsbuildConfig( + rawBuildConfig as RsbuildConfig, + environmentConfig as RsbuildConfig, + ) + : (rawBuildConfig as RsbuildConfig); + + // Allow modification of rsbuild config + const finalBuildConfig = modifyRsbuildConfig + ? modifyRsbuildConfig(rsbuildConfig) + : rsbuildConfig; + + const { rspack, swc, bundlerChain } = finalBuildConfig.tools || {}; + const { cssModules, target, module } = finalBuildConfig.output || {}; + const { decorators, define, include, exclude, tsconfigPath } = + finalBuildConfig.source || {}; + + // Convert rsbuild config to rstest config + const rstestConfig: ExtendConfig = { + // Copy over compatible configurations + root: finalBuildConfig.root, + name: environmentName, + plugins: finalBuildConfig.plugins, + source: { + decorators, + define, + include, + exclude, + tsconfigPath, + }, + resolve: finalBuildConfig.resolve, + output: { + cssModules, + module, + }, + tools: { + rspack, + swc, + bundlerChain, + } as ExtendConfig['tools'], + + testEnvironment: target === 'node' ? 'node' : 'happy-dom', + }; + + return rstestConfig; + }; +} diff --git a/packages/adapter-rsbuild/tests/index.test.ts b/packages/adapter-rsbuild/tests/index.test.ts new file mode 100644 index 000000000..7da963751 --- /dev/null +++ b/packages/adapter-rsbuild/tests/index.test.ts @@ -0,0 +1,105 @@ +import { existsSync, unlinkSync, writeFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { afterEach, beforeEach, describe, expect, it } from '@rstest/core'; +import { withRsbuildConfig } from '../src'; + +describe('withRsbuildConfig', () => { + const testConfigPath = join(__dirname, 'test-temp-rsbuild.config.ts'); + const testConfigContent = ` +import { defineConfig } from '@rsbuild/core'; + +export default defineConfig({ + source: { + define: { + 'process.env.NODE_ENV': '"common"' + } + }, + resolve: { + alias: { + '@': './src' + } + }, + environments: { + test: { + source: { + define: { + 'process.env.NODE_ENV': '"test"' + } + } + } + } +}); + `; + + beforeEach(() => { + // Create a temporary rsbuild config file for testing + writeFileSync(testConfigPath, testConfigContent); + }); + + afterEach(() => { + // Clean up test config file + if (existsSync(testConfigPath)) { + unlinkSync(testConfigPath); + } + }); + + it('should load and convert rsbuild config to rstest config', async () => { + const config = await withRsbuildConfig({ + configPath: testConfigPath, + })({}); + + expect(config).toBeDefined(); + expect(config.source?.define).toEqual({ + 'process.env.NODE_ENV': '"common"', + }); + expect(config.resolve?.alias).toEqual({ + '@': './src', + }); + expect(config.testEnvironment).toBe('happy-dom'); + }); + + it('should load and merge environment config', async () => { + const config = await withRsbuildConfig({ + configPath: testConfigPath, + environmentName: 'test', + })({}); + + expect(config).toBeDefined(); + expect(config.name).toBe('test'); + expect(config.source?.define).toEqual({ + 'process.env.NODE_ENV': '"test"', + }); + expect(config.resolve?.alias).toEqual({ + '@': './src', + }); + }); + + it('should allow modification of rsbuild config', async () => { + const config = await withRsbuildConfig({ + configPath: testConfigPath, + modifyRsbuildConfig: (rsbuildConfig) => ({ + ...rsbuildConfig, + source: { + ...rsbuildConfig.source, + define: { + ...rsbuildConfig.source?.define, + 'process.env.CUSTOM': '"custom-value"', + }, + }, + }), + })({}); + + expect(config.source?.define).toEqual({ + 'process.env.NODE_ENV': '"common"', + 'process.env.CUSTOM': '"custom-value"', + }); + }); + + it('should throw error when config file not found', async () => { + await expect(() => + withRsbuildConfig({ + configPath: './non-existent.config.ts', + })({}), + ).rejects.toThrowError(/Cannot find config file/); + }); +}); diff --git a/packages/adapter-rsbuild/tsconfig.json b/packages/adapter-rsbuild/tsconfig.json new file mode 100644 index 000000000..6dcf8e281 --- /dev/null +++ b/packages/adapter-rsbuild/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@rstest/tsconfig/base", + "compilerOptions": { + "outDir": "./dist", + "baseUrl": "./", + "rootDir": "src", + "composite": true, + "isolatedDeclarations": true + }, + "include": ["src"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc14b1452..41196361d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -428,6 +428,9 @@ importers: '@rsbuild/plugin-react': specifier: ^1.4.2 version: 1.4.2(@rsbuild/core@1.7.1) + '@rstest/adapter-rsbuild': + specifier: workspace:* + version: link:../../packages/adapter-rsbuild '@testing-library/dom': specifier: ^10.4.1 version: 10.4.1 @@ -443,13 +446,28 @@ importers: '@types/react-dom': specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.7) - jsdom: - specifier: ^26.1.0 - version: 26.1.0 + happy-dom: + specifier: ^20.0.11 + version: 20.0.11 typescript: specifier: ^5.9.3 version: 5.9.3 + packages/adapter-rsbuild: + devDependencies: + '@rsbuild/core': + specifier: ^1.7.1 + version: 1.7.1 + '@rslib/core': + specifier: ^0.19.0 + version: 0.19.0(@microsoft/api-extractor@7.55.2(@types/node@22.18.6))(typescript@5.9.3) + '@rstest/core': + specifier: workspace:* + version: link:../core + '@rstest/tsconfig': + specifier: workspace:* + version: link:../../scripts/tsconfig + packages/adapter-rslib: devDependencies: '@rslib/core': diff --git a/website/docs/en/guide/integration/_meta.json b/website/docs/en/guide/integration/_meta.json index ea9a7b5ee..98b4ca3bd 100644 --- a/website/docs/en/guide/integration/_meta.json +++ b/website/docs/en/guide/integration/_meta.json @@ -1 +1 @@ -["adapters", "rslib"] +["adapters", "rslib", "rsbuild"] diff --git a/website/docs/en/guide/integration/adapters.mdx b/website/docs/en/guide/integration/adapters.mdx index def490dc2..864cca460 100644 --- a/website/docs/en/guide/integration/adapters.mdx +++ b/website/docs/en/guide/integration/adapters.mdx @@ -164,3 +164,4 @@ In this way, you can create powerful and reusable adapters that seamlessly integ The following are the officially supported Rstest adapters: - [Rslib Adapter](/guide/integration/rslib#install-adapter): Used to extend Rstest configuration from Rslib configuration. +- [Rsbuild Adapter](/guide/integration/rsbuild#install-adapter): Used to extend Rstest configuration from Rsbuild configuration. diff --git a/website/docs/en/guide/integration/rsbuild.mdx b/website/docs/en/guide/integration/rsbuild.mdx new file mode 100644 index 000000000..eb751fbbe --- /dev/null +++ b/website/docs/en/guide/integration/rsbuild.mdx @@ -0,0 +1,101 @@ +# Rsbuild + +This guide covers how to integrate Rstest with [Rsbuild](https://rsbuild.dev) for seamless testing in your Rsbuild projects. + +## Quick start + +### New project + +Create a new Rsbuild + Rstest project. Add the `--tools rstest` flag when creating: + +```bash +npm create rsbuild@latest -- --tools rstest +``` + +The scaffold includes Rstest and demo tests. Run them with `npm run test`. + +### Existing project + +To add Rstest to an existing project, follow the [Quick Start](/guide/start/quick-start) to install and set up test scripts. + +## Reuse Rsbuild config + +[@rstest/adapter-rsbuild](https://www.npmjs.com/package/@rstest/adapter-rsbuild) is an official adapter that allows Rstest to automatically inherit configuration from your existing Rsbuild config file. This ensures your test environment matches your build configuration without duplication. + +### Install adapter + +import { PackageManagerTabs } from '@theme'; + + + +### Extend your config + +Using the `withRsbuildConfig` function from the adapter, you can extend your Rstest configuration from the Rsbuild config file. + +```typescript +import { defineConfig } from '@rstest/core'; +import { withRsbuildConfig } from '@rstest/adapter-rsbuild'; + +export default defineConfig({ + extends: withRsbuildConfig(), + // Additional rstest-specific configuration +}); +``` + +This will automatically: + +- Load your `rsbuild.config.ts` file +- Map compatible Rsbuild options to Rstest configuration +- Merge with any additional Rstest config you provide + +By default, the adapter uses `process.cwd()` to resolve the Rsbuild config. If your config lives elsewhere, set `cwd`: + +```ts +export default defineConfig({ + extends: withRsbuildConfig({ + cwd: './packages/my-app', + }), +}); +``` + +See the [`@rstest/adapter-rsbuild` documentation](https://www.npmjs.com/package/@rstest/adapter-rsbuild) for advanced options. + +### Configuration mapping + +The adapter automatically maps these Rsbuild options to Rstest: + +| Rsbuild option | Rstest equivalent | Notes | +| ----------------------- | --------------------- | ------------------------------------ | +| `name` from environment | `name` | Environment identifier | +| `plugins` | `plugins` | Plugin configuration | +| `source.decorators` | `source.decorators` | Decorator support | +| `source.define` | `source.define` | Global constants | +| `source.include` | `source.include` | Source inclusion patterns | +| `source.exclude` | `source.exclude` | Source exclusion patterns | +| `source.tsconfigPath` | `source.tsconfigPath` | TypeScript config path | +| `resolve` | `resolve` | Module resolution | +| `output.cssModules` | `output.cssModules` | CSS modules configuration | +| `tools.rspack` | `tools.rspack` | Rspack configuration | +| `tools.swc` | `tools.swc` | SWC configuration | +| `tools.bundlerChain` | `tools.bundlerChain` | Bundler chain configuration | +| `output.target` | `testEnvironment` | 'happy-dom' for web, 'node' for node | + +### Debug config + +To see the resolved configuration returned by the adapter, wrap it and log the result: + +```typescript +export default defineConfig({ + extends: async (user) => { + const config = await withRsbuildConfig()(user); + console.log('Extended config:', JSON.stringify(config, null, 2)); + return config; + }, +}); +``` + +## Related documentation + +- [`@rstest/adapter-rsbuild` documentation](https://www.npmjs.com/package/@rstest/adapter-rsbuild) +- [Rsbuild configuration overview](https://rsbuild.dev/config) +- [Rstest configuration overview](/config/) diff --git a/website/docs/zh/guide/integration/_meta.json b/website/docs/zh/guide/integration/_meta.json index ea9a7b5ee..98b4ca3bd 100644 --- a/website/docs/zh/guide/integration/_meta.json +++ b/website/docs/zh/guide/integration/_meta.json @@ -1 +1 @@ -["adapters", "rslib"] +["adapters", "rslib", "rsbuild"] diff --git a/website/docs/zh/guide/integration/adapters.mdx b/website/docs/zh/guide/integration/adapters.mdx index 5adf75e8e..228c6ff46 100644 --- a/website/docs/zh/guide/integration/adapters.mdx +++ b/website/docs/zh/guide/integration/adapters.mdx @@ -164,3 +164,4 @@ export default defineConfig({ 以下是 Rstest 官方支持的适配器: - [Rslib Adapter](/guide/integration/rslib#安装适配器):用于从 Rslib 配置中扩展 Rstest 配置。 +- [Rsbuild Adapter](/guide/integration/rsbuild#安装适配器):用于从 Rsbuild 配置中扩展 Rstest 配置。 diff --git a/website/docs/zh/guide/integration/rsbuild.mdx b/website/docs/zh/guide/integration/rsbuild.mdx new file mode 100644 index 000000000..aa01644ce --- /dev/null +++ b/website/docs/zh/guide/integration/rsbuild.mdx @@ -0,0 +1,101 @@ +# Rsbuild + +本指南介绍了如何将 Rstest 与 [Rsbuild](https://rsbuild.dev) 集成,以便在你的 Rsbuild 项目中进行无缝测试。 + +## 快速开始 + +### 新建项目 + +创建一个新的 Rsbuild + Rstest 项目。在创建时添加 `--tools rstest` 标志: + +```bash +npm create rsbuild@latest -- --tools rstest +``` + +脚手架包含了 Rstest 和演示测试。使用 `npm run test` 来运行它们。 + +### 现有项目 + +要将 Rstest 添加到现有项目中,请遵循[快速入门](/guide/start/quick-start)来安装和设置测试脚本。 + +## 复用 Rsbuild 配置 + +[@rstest/adapter-rsbuild](https://www.npmjs.com/package/@rstest/adapter-rsbuild) 是一个官方适配器,它允许 Rstest 自动从你现有的 Rsbuild 配置文件中继承配置。这可以确保你的测试环境与构建配置相匹配,而无需重复配置。 + +### 安装适配器 + +import { PackageManagerTabs } from '@theme'; + + + +### 继承你的配置 + +使用适配器中的 `withRsbuildConfig` 函数,你可以从 Rsbuild 配置文件中继承 Rstest 配置。 + +```typescript +import { defineConfig } from '@rstest/core'; +import { withRsbuildConfig } from '@rstest/adapter-rsbuild'; + +export default defineConfig({ + extends: withRsbuildConfig(), + // 额外的 rstest 特定配置 +}); +``` + +这将自动: + +- 加载你的 `rsbuild.config.ts` 文件 +- 将兼容的 Rsbuild 选项映射到 Rstest 配置 +- 与你提供的任何其他 Rstest 配置合并 + +默认情况下,适配器使用 `process.cwd()` 来解析 Rsbuild 配置。如果你的配置文件在其他地方,请设置 `cwd`: + +```ts +export default defineConfig({ + extends: withRsbuildConfig({ + cwd: './packages/my-app', + }), +}); +``` + +有关高级选项,请参阅 [`@rstest/adapter-rsbuild` 文档](https://www.npmjs.com/package/@rstest/adapter-rsbuild)。 + +### 配置映射 + +适配器会自动将这些 Rsbuild 选项映射到 Rstest: + +| Rsbuild 选项 | Rstest 等效项 | 说明 | +| ----------------------- | --------------------- | ------------------------------------------ | +| `name` from environment | `name` | 环境标识符 | +| `plugins` | `plugins` | 插件配置 | +| `source.decorators` | `source.decorators` | 装饰器支持 | +| `source.define` | `source.define` | 全局常量 | +| `source.include` | `source.include` | 源文件包含模式 | +| `source.exclude` | `source.exclude` | 源文件排除模式 | +| `source.tsconfigPath` | `source.tsconfigPath` | TypeScript 配置文件路径 | +| `resolve` | `resolve` | 模块解析 | +| `output.cssModules` | `output.cssModules` | CSS 模块配置 | +| `tools.rspack` | `tools.rspack` | Rspack 配置 | +| `tools.swc` | `tools.swc` | SWC 配置 | +| `tools.bundlerChain` | `tools.bundlerChain` | Bundler 链配置 | +| `output.target` | `testEnvironment` | web 环境为 'happy-dom',node 环境为 'node' | + +### 调试配置 + +要查看适配器返回的解析配置,可以将其包装并打印结果: + +```typescript +export default defineConfig({ + extends: async (user) => { + const config = await withRsbuildConfig()(user); + console.log('继承的配置:', JSON.stringify(config, null, 2)); + return config; + }, +}); +``` + +## 相关文档 + +- [`@rstest/adapter-rsbuild` 文档](https://www.npmjs.com/package/@rstest/adapter-rsbuild) +- [Rsbuild 配置概览](https://rsbuild.dev/config) +- [Rstest 配置概览](/config/) From 47faca2c7d07ca143655abb649ed59297954d9e5 Mon Sep 17 00:00:00 2001 From: 9aoy <9aoyuao@gmail.com> Date: Mon, 5 Jan 2026 19:29:35 +0800 Subject: [PATCH 2/6] fix: cwd --- examples/react/rstest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/react/rstest.config.ts b/examples/react/rstest.config.ts index c7439e502..e95e1c309 100644 --- a/examples/react/rstest.config.ts +++ b/examples/react/rstest.config.ts @@ -2,6 +2,6 @@ import { withRsbuildConfig } from '@rstest/adapter-rsbuild'; import { defineConfig } from '@rstest/core'; export default defineConfig({ - extends: withRsbuildConfig(), + extends: withRsbuildConfig({ cwd: __dirname }), setupFiles: ['./rstest.setup.ts'], }); From 71a4689910e874fb1ba7d6f56d16f133b7de6db8 Mon Sep 17 00:00:00 2001 From: 9aoy <9aoyuao@gmail.com> Date: Mon, 5 Jan 2026 19:39:24 +0800 Subject: [PATCH 3/6] fix: lint --- packages/adapter-rsbuild/package.json | 2 +- pnpm-lock.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/adapter-rsbuild/package.json b/packages/adapter-rsbuild/package.json index 8da704046..3c553e7c5 100644 --- a/packages/adapter-rsbuild/package.json +++ b/packages/adapter-rsbuild/package.json @@ -31,7 +31,7 @@ }, "devDependencies": { "@rslib/core": "^0.19.0", - "@rsbuild/core": "^1.7.1", + "@rsbuild/core": "1.7.1", "@rstest/core": "workspace:*", "@rstest/tsconfig": "workspace:*" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 41196361d..46f0a78e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -456,7 +456,7 @@ importers: packages/adapter-rsbuild: devDependencies: '@rsbuild/core': - specifier: ^1.7.1 + specifier: 1.7.1 version: 1.7.1 '@rslib/core': specifier: ^0.19.0 From 1eb5c8dc440384820a7f5c2ae30b4df04dcd1468 Mon Sep 17 00:00:00 2001 From: 9aoy <9aoyuao@gmail.com> Date: Tue, 6 Jan 2026 11:11:28 +0800 Subject: [PATCH 4/6] Update packages/adapter-rsbuild/README.md Co-authored-by: neverland --- packages/adapter-rsbuild/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adapter-rsbuild/README.md b/packages/adapter-rsbuild/README.md index 5484fa7a8..6254d1221 100644 --- a/packages/adapter-rsbuild/README.md +++ b/packages/adapter-rsbuild/README.md @@ -1,6 +1,6 @@ # @rstest/adapter-rsbuild -Rstest adapter for [Rsbuild](https://rsbuild.dev) configuration. This package allows you to extend your Rstest configuration from Rsbuild config files. +Rstest adapter for [Rsbuild](https://rsbuild.rs) configuration. This package allows you to extend your Rstest configuration from Rsbuild config files. ## Installation From 2c2a47b62e7d1bbe3d7f327ecdb01a81e168e785 Mon Sep 17 00:00:00 2001 From: 9aoy <9aoyuao@gmail.com> Date: Tue, 6 Jan 2026 11:11:39 +0800 Subject: [PATCH 5/6] Update website/docs/en/guide/integration/rsbuild.mdx Co-authored-by: neverland --- website/docs/en/guide/integration/rsbuild.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/en/guide/integration/rsbuild.mdx b/website/docs/en/guide/integration/rsbuild.mdx index eb751fbbe..a02890d38 100644 --- a/website/docs/en/guide/integration/rsbuild.mdx +++ b/website/docs/en/guide/integration/rsbuild.mdx @@ -84,7 +84,7 @@ The adapter automatically maps these Rsbuild options to Rstest: To see the resolved configuration returned by the adapter, wrap it and log the result: -```typescript +```ts export default defineConfig({ extends: async (user) => { const config = await withRsbuildConfig()(user); From 140339dc6aa6f9d76a89a445bdf06640b52dca96 Mon Sep 17 00:00:00 2001 From: 9aoy <9aoyuao@gmail.com> Date: Tue, 6 Jan 2026 14:37:32 +0800 Subject: [PATCH 6/6] chore: move API documentation --- packages/adapter-rsbuild/README.md | 130 +----------------- website/docs/en/guide/integration/rsbuild.mdx | 112 ++++++++++++++- website/docs/zh/guide/integration/rsbuild.mdx | 112 ++++++++++++++- 3 files changed, 215 insertions(+), 139 deletions(-) diff --git a/packages/adapter-rsbuild/README.md b/packages/adapter-rsbuild/README.md index 6254d1221..ee1a9aff8 100644 --- a/packages/adapter-rsbuild/README.md +++ b/packages/adapter-rsbuild/README.md @@ -20,132 +20,4 @@ export default defineConfig({ }); ``` -## API - -### withRsbuildConfig(options) - -Returns a configuration function that loads Rsbuild config and converts it to Rstest configuration. - -#### Options - -- `cwd` (string): `cwd` passed to loadConfig of Rsbuild. Default: `process.cwd()` -- `configPath` (string): Path to rsbuild config file. Default: `'./rsbuild.config.ts'` -- `environmentName` (string): The environment name in `environments` field to use, will be merged with the common config. Set to a string to use the environment config with matching name. Default: `undefined` -- `modifyRsbuildConfig` (function): Modify rsbuild config before converting to rstest config. Default: `undefined` - -The adapter automatically copies and maps compatible configuration options from Rsbuild to Rstest: - -**From Rsbuild → to Rstest:** - -The adapter automatically maps these Rsbuild options to Rstest: - -| Rsbuild option | Rstest equivalent | Notes | -| ----------------------- | --------------------- | ------------------------------------ | -| `name` from environment | `name` | Environment identifier | -| `plugins` | `plugins` | Plugin configuration | -| `source.decorators` | `source.decorators` | Decorator support | -| `source.define` | `source.define` | Global constants | -| `source.include` | `source.include` | Source inclusion patterns | -| `source.exclude` | `source.exclude` | Source exclusion patterns | -| `source.tsconfigPath` | `source.tsconfigPath` | TypeScript config path | -| `resolve` | `resolve` | Module resolution | -| `output.cssModules` | `output.cssModules` | CSS modules configuration | -| `tools.rspack` | `tools.rspack` | Rspack configuration | -| `tools.swc` | `tools.swc` | SWC configuration | -| `tools.bundlerChain` | `tools.bundlerChain` | Bundler chain configuration | -| `output.target` | `testEnvironment` | 'happy-dom' for web, 'node' for node | - -## Advanced usage - -### Specifying working directory - -By default, the adapter uses `process.cwd()` as the working directory to resolve the Rsbuild config file. - -When your Rsbuild config is in a different directory or you are running tests in a monorepo (which your `process.cwd()` is not your config directory), you can specify the `cwd` option to resolve the Rsbuild config file from a different directory. - -```ts -export default defineConfig({ - extends: withRsbuildConfig({ - cwd: './packages/my-app', - }), -}); -``` - -### Using specific environment configuration - -By default, the adapter uses the common configuration from Rsbuild. - -If your Rsbuild config has multiple environment configurations: - -```ts -// rsbuild.config.ts -export default { - source: { - define: { - 'process.env.NODE_ENV': '"development"', - }, - }, - environments: { - test: { - source: { - define: { - 'process.env.NODE_ENV': '"test"', - }, - }, - }, - prod: { - source: { - define: { - 'process.env.NODE_ENV': '"production"', - }, - }, - }, - }, -}; -``` - -You can then reference specific environment configurations in your Rstest config. Rstest will adapt the Rsbuild shared configuration and the environment configuration with a matching `environmentName` to Rstest format. - -```ts -// For testing the 'test' environment -export default defineConfig({ - extends: withRsbuildConfig({ - environmentName: 'test', - }), - // test-environment-specific config -}); -``` - -### Multiple environment configurations - -When you need to test multiple parts of your application with different configurations independently, you can define multiple Rstest projects. Each project can extend a specific environment configuration by setting the `environmentName` option. - -```ts -export default defineConfig({ - projects: [ - { - extends: withRsbuildConfig({ environmentName: 'node' }), - include: ['tests/node/**/*.{test,spec}.?(c|m)[jt]s'], - }, - { - extends: withRsbuildConfig({ environmentName: 'react' }), - include: ['tests/react/**/*.{test,spec}.?(c|m)[jt]s?(x)'], - }, - ], -}); -``` - -### Modifying Rsbuild config - -You can modify the Rsbuild config before it gets converted to Rstest config: - -```ts -export default defineConfig({ - extends: withRsbuildConfig({ - modifyRsbuildConfig: (rsbuildConfig) => { - delete rsbuildConfig.source?.define; - return rsbuildConfig; - }, - }), -}); -``` +More advanced usage examples can be found in the [Rsbuild integration guide](https://rstest.rs/guide/integration/rsbuild). diff --git a/website/docs/en/guide/integration/rsbuild.mdx b/website/docs/en/guide/integration/rsbuild.mdx index a02890d38..702511ce7 100644 --- a/website/docs/en/guide/integration/rsbuild.mdx +++ b/website/docs/en/guide/integration/rsbuild.mdx @@ -48,7 +48,22 @@ This will automatically: - Map compatible Rsbuild options to Rstest configuration - Merge with any additional Rstest config you provide -By default, the adapter uses `process.cwd()` to resolve the Rsbuild config. If your config lives elsewhere, set `cwd`: +By default, the adapter uses `process.cwd()` to resolve the Rsbuild config. If your config lives elsewhere, you can use the `cwd` option. See [API](#api) for more details. + +## API + +### `withRsbuildConfig(options)` + +Returns a configuration function that loads Rsbuild config and converts it to Rstest configuration. + +#### `cwd` + +- **Type:** `string` +- **Default:** `process.cwd()` + +The `cwd` is passed to Rsbuild's `loadConfig` function. It's the working directory to resolve the Rsbuild config file. + +When your Rsbuild config is in a different directory or you are running tests in a monorepo (where your `process.cwd()` is not your config directory), you can specify the `cwd` option to resolve the Rsbuild config file from a different directory. ```ts export default defineConfig({ @@ -58,9 +73,97 @@ export default defineConfig({ }); ``` -See the [`@rstest/adapter-rsbuild` documentation](https://www.npmjs.com/package/@rstest/adapter-rsbuild) for advanced options. +#### `configPath` + +- **Type:** `string` +- **Default:** `'./rsbuild.config.ts'` + +Path to rsbuild config file. + +#### `environmentName` + +- **Type:** `string` +- **Default:** `undefined` + +The environment name in the `environments` field to use, which will be merged with the common config. Set to a string to use the environment config with a matching name. + +By default, the adapter uses the common configuration from Rsbuild. If your Rsbuild config has multiple environment configurations: + +```ts +// rsbuild.config.ts +export default { + source: { + define: { + 'process.env.NODE_ENV': '"development"', + }, + }, + environments: { + test: { + source: { + define: { + 'process.env.NODE_ENV': '"test"', + }, + }, + }, + prod: { + source: { + define: { + 'process.env.NODE_ENV': '"production"', + }, + }, + }, + }, +}; +``` + +You can then reference specific environment configurations in your Rstest config. Rstest will adapt the Rsbuild shared configuration and the environment configuration with a matching `environmentName` to Rstest format. + +```ts +// For testing the 'test' environment +export default defineConfig({ + extends: withRsbuildConfig({ + environmentName: 'test', + }), + // test-environment-specific config +}); +``` + +When you need to test multiple parts of your application with different configurations independently, you can define multiple Rstest projects. Each project can extend a specific environment configuration by setting the `environmentName` option. + +```ts +export default defineConfig({ + projects: [ + { + extends: withRsbuildConfig({ environmentName: 'node' }), + include: ['tests/node/**/*.{test,spec}.?(c|m)[jt]s'], + }, + { + extends: withRsbuildConfig({ environmentName: 'react' }), + include: ['tests/react/**/*.{test,spec}.?(c|m)[jt]s?(x)'], + }, + ], +}); +``` + +#### `modifyRsbuildConfig` + +- **Type:** `(config: RsbuildConfig) => RsbuildConfig | void` +- **Default:** `undefined` + +Modify the Rsbuild config before it gets converted to Rstest config: + +```ts +export default defineConfig({ + extends: withRsbuildConfig({ + modifyRsbuildConfig: (rsbuildConfig) => { + delete rsbuildConfig.source?.define; + return rsbuildConfig; + }, + }), +}); +``` -### Configuration mapping +## Configuration mapping The adapter automatically maps these Rsbuild options to Rstest: @@ -80,7 +183,7 @@ The adapter automatically maps these Rsbuild options to Rstest: | `tools.bundlerChain` | `tools.bundlerChain` | Bundler chain configuration | | `output.target` | `testEnvironment` | 'happy-dom' for web, 'node' for node | -### Debug config +## Debug config To see the resolved configuration returned by the adapter, wrap it and log the result: @@ -96,6 +199,5 @@ export default defineConfig({ ## Related documentation -- [`@rstest/adapter-rsbuild` documentation](https://www.npmjs.com/package/@rstest/adapter-rsbuild) - [Rsbuild configuration overview](https://rsbuild.dev/config) - [Rstest configuration overview](/config/) diff --git a/website/docs/zh/guide/integration/rsbuild.mdx b/website/docs/zh/guide/integration/rsbuild.mdx index aa01644ce..2a244e965 100644 --- a/website/docs/zh/guide/integration/rsbuild.mdx +++ b/website/docs/zh/guide/integration/rsbuild.mdx @@ -48,7 +48,22 @@ export default defineConfig({ - 将兼容的 Rsbuild 选项映射到 Rstest 配置 - 与你提供的任何其他 Rstest 配置合并 -默认情况下,适配器使用 `process.cwd()` 来解析 Rsbuild 配置。如果你的配置文件在其他地方,请设置 `cwd`: +默认情况下,适配器使用 `process.cwd()` 来解析 Rsbuild 配置。如果你的配置文件在其他地方,你可以使用 `cwd` 选项。更多详情请参阅 [API](#api) 部分。 + +## API + +### `withRsbuildConfig(options)` + +返回一个配置函数,该函数加载 Rsbuild 配置并将其转换为 Rstest 配置。 + +#### `cwd` + +- **类型:** `string` +- **默认值:** `process.cwd()` + +`cwd` 会传递给 Rsbuild 的 `loadConfig` 函数。它是用于解析 Rsbuild 配置文件的当前工作目录。 + +当你的 Rsbuild 配置文件位于不同的目录,或者你在 monorepo 中运行测试(此时 `process.cwd()` 不是你的配置目录)时,你可以指定 `cwd` 选项从不同的目录解析 Rsbuild 配置文件。 ```ts export default defineConfig({ @@ -58,9 +73,97 @@ export default defineConfig({ }); ``` -有关高级选项,请参阅 [`@rstest/adapter-rsbuild` 文档](https://www.npmjs.com/package/@rstest/adapter-rsbuild)。 +#### `configPath` + +- **类型:** `string` +- **默认值:** `'./rsbuild.config.ts'` + +Rsbuild 配置文件的路径。 + +#### `environmentName` + +- **类型:** `string` +- **默认值:** `undefined` + +要使用的 `environments` 字段中的环境名称,它将与通用配置合并。设置为一个字符串以使用具有匹配名称的环境配置。 + +默认情况下,适配器使用 Rsbuild 的通用配置。如果你的 Rsbuild 配置有多个环境配置: + +```ts +// rsbuild.config.ts +export default { + source: { + define: { + 'process.env.NODE_ENV': '"development"', + }, + }, + environments: { + test: { + source: { + define: { + 'process.env.NODE_ENV': '"test"', + }, + }, + }, + prod: { + source: { + define: { + 'process.env.NODE_ENV': '"production"', + }, + }, + }, + }, +}; +``` + +你可以在 Rstest 配置中引用特定的环境配置。Rstest 将会把 Rsbuild 的共享配置和具有匹配 `environmentName` 的环境配置适配为 Rstest 格式。 + +```ts +// 用于测试 'test' 环境 +export default defineConfig({ + extends: withRsbuildConfig({ + environmentName: 'test', + }), + // 测试环境特定的配置 +}); +``` + +当你需要使用不同的配置独立测试应用程序的多个部分时,你可以定义多个 Rstest 项目。每个项目可以通过设置 `environmentName` 选项来继承特定的环境配置。 + +```ts +export default defineConfig({ + projects: [ + { + extends: withRsbuildConfig({ environmentName: 'node' }), + include: ['tests/node/**/*.{test,spec}.?(c|m)[jt]s'], + }, + { + extends: withRsbuildConfig({ environmentName: 'react' }), + include: ['tests/react/**/*.{test,spec}.?(c|m)[jt]s?(x)'], + }, + ], +}); +``` + +#### `modifyRsbuildConfig` + +- **类型:** `(config: RsbuildConfig) => RsbuildConfig | void` +- **默认值:** `undefined` + +在将 Rsbuild 配置转换为 Rstest 配置之前对其进行修改: + +```ts +export default defineConfig({ + extends: withRsbuildConfig({ + modifyRsbuildConfig: (rsbuildConfig) => { + delete rsbuildConfig.source?.define; + return rsbuildConfig; + }, + }), +}); +``` -### 配置映射 +## 配置映射 适配器会自动将这些 Rsbuild 选项映射到 Rstest: @@ -80,7 +183,7 @@ export default defineConfig({ | `tools.bundlerChain` | `tools.bundlerChain` | Bundler 链配置 | | `output.target` | `testEnvironment` | web 环境为 'happy-dom',node 环境为 'node' | -### 调试配置 +## 调试配置 要查看适配器返回的解析配置,可以将其包装并打印结果: @@ -96,6 +199,5 @@ export default defineConfig({ ## 相关文档 -- [`@rstest/adapter-rsbuild` 文档](https://www.npmjs.com/package/@rstest/adapter-rsbuild) - [Rsbuild 配置概览](https://rsbuild.dev/config) - [Rstest 配置概览](/config/)