feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,217 @@
# @coze-arch/vitest-config
> Shared Vitest configuration for the Coze architecture ecosystem
A unified testing configuration package that provides optimized Vitest setups for Node.js and web applications in the Coze monorepo. This package simplifies test configuration management and ensures consistency across all projects.
## Features
- **Multiple Presets**: Pre-configured setups for `default`, `node`, and `web` environments
- **TypeScript Support**: Built-in TypeScript path mapping with `vite-tsconfig-paths`
- **React Testing**: Web preset includes React plugin for component testing
- **Coverage Reporting**: Comprehensive coverage configuration with multiple reporters
- **Performance Optimized**: Fork-based test execution with configurable pool options
- **Semi-UI Compatibility**: Special handling for Semi Design components
- **Flexible Configuration**: Easy to extend and customize for specific project needs
## Get Started
### Installation
Add the package to your project:
```bash
# In your package.json
{
"devDependencies": {
"@coze-arch/vitest-config": "workspace:*"
}
}
```
Then run:
```bash
rush update
```
### Basic Usage
Create a `vitest.config.ts` file in your project root:
```typescript
import { defineConfig } from '@coze-arch/vitest-config';
export default defineConfig({
dirname: __dirname,
preset: 'web', // or 'node' or 'default'
});
```
## API Reference
### `defineConfig(config, otherConfig?)`
The main configuration function that creates a Vitest configuration based on your requirements.
#### Parameters
**config** (`VitestConfig`):
- `dirname` (string, required): The project root directory (`__dirname`)
- `preset` (string, required): Configuration preset - `'default'` | `'node'` | `'web'`
- All other Vitest configuration options
**otherConfig** (`OtherConfig`, optional):
- `fixSemi` (boolean): Enable Semi Design component compatibility fixes
#### Examples
**Default Configuration:**
```typescript
import { defineConfig } from '@coze-arch/vitest-config';
export default defineConfig({
dirname: __dirname,
preset: 'default',
});
```
**Node.js Application:**
```typescript
import { defineConfig } from '@coze-arch/vitest-config';
export default defineConfig({
dirname: __dirname,
preset: 'node',
test: {
include: ['src/**/*.test.ts'],
exclude: ['src/**/*.browser.test.ts'],
},
});
```
**React/Web Application:**
```typescript
import { defineConfig } from '@coze-arch/vitest-config';
export default defineConfig({
dirname: __dirname,
preset: 'web',
test: {
include: ['src/**/*.{test,spec}.{ts,tsx}'],
setupFiles: ['./src/test-setup.ts'],
},
});
```
**With Semi Design Components:**
```typescript
import { defineConfig } from '@coze-arch/vitest-config';
export default defineConfig({
dirname: __dirname,
preset: 'web',
}, {
fixSemi: true,
});
```
**Custom Coverage Configuration:**
```typescript
import { defineConfig } from '@coze-arch/vitest-config';
export default defineConfig({
dirname: __dirname,
preset: 'web',
test: {
coverage: {
all: true,
threshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
},
},
});
```
### Available Presets
#### `default`
- Basic Vitest configuration
- TypeScript path mapping
- Fork-based test execution
- Coverage reporting disabled by default
#### `node`
- Extends default preset
- Optimized for Node.js applications
- No browser-specific plugins
#### `web`
- Extends default preset
- Includes React plugin for JSX/TSX support
- Uses `happy-dom` environment for DOM testing
- Optimized for frontend applications
### Built-in Features
**Test Execution:**
- Pool: `forks` with 1-32 workers
- Parallel hook execution
- Global test APIs enabled
- Silent mode in CI environments
**Coverage:**
- Provider: V8
- Formats: Cobertura, Text, HTML, Clover, JSON
- Includes: `src/**/*.ts`, `src/**/*.tsx`
- Excludes: Standard Vitest defaults
**TypeScript:**
- Automatic path mapping via `vite-tsconfig-paths`
- Resolve main fields: `main`, `module`, `exports`
## Development
### Scripts
```bash
# Lint the code
rush lint
# Development mode
rush dev
```
### Project Structure
```
src/
├── index.js # CommonJS entry point with Sucrase
├── define-config.ts # Main configuration function
├── preset-default.ts # Base configuration preset
├── preset-node.ts # Node.js specific preset
├── preset-web.ts # Web/React specific preset
└── tsc-only.ts # TypeScript-only mock file
```
## Dependencies
### Production Dependencies
- `vite-tsconfig-paths`: TypeScript path mapping support
### Development Dependencies
- `vitest`: Core testing framework
- `@vitejs/plugin-react`: React support for web preset
- `@vitest/coverage-v8`: Coverage reporting
- `happy-dom`: Lightweight DOM environment
- `sucrase`: Fast TypeScript compilation
## License
This package is part of the Coze architecture ecosystem and follows the project's licensing terms.

View File

@@ -0,0 +1,8 @@
{
"operationSettings": [
{
"operationName": "ts-check",
"outputFolderNames": ["dist"]
}
]
}

View File

@@ -0,0 +1,6 @@
const { defineConfig } = require('@coze-arch/eslint-config');
module.exports = defineConfig({
preset: 'node',
packageRoot: __dirname,
});

View File

@@ -0,0 +1,25 @@
{
"name": "@coze-arch/vitest-config",
"version": "0.0.1",
"author": "fanwenjie.fe@bytedance.com",
"maintainers": [],
"main": "src/index.js",
"types": "src/define-config.ts",
"scripts": {
"dev": "npm run build -- -w",
"lint": "eslint ./ --cache --quiet"
},
"dependencies": {
"vite-tsconfig-paths": "^4.2.1"
},
"devDependencies": {
"@coze-arch/eslint-config": "workspace:*",
"@coze-arch/ts-config": "workspace:*",
"@types/node": "^18",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "~3.0.5",
"happy-dom": "^12.10.3",
"sucrase": "^3.32.0",
"vitest": "~3.0.5"
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { resolve } from 'path';
import { mergeConfig, type UserConfig } from 'vitest/config';
import { webPreset } from './preset-web';
import { nodePreset } from './preset-node';
import { defaultVitestConfig } from './preset-default';
export interface VitestConfig extends UserConfig {
/**
* A string representing the project root directory.
*/
dirname: string;
/**
* A string representing the preset configuration style, which can be one of 'default', 'node', or 'web'.
*/
preset: 'default' | 'node' | 'web';
}
const calBasePreset = (preset: string) => {
switch (preset) {
case 'node':
return nodePreset;
case 'web':
return webPreset;
default:
return defaultVitestConfig;
}
};
export interface OtherConfig {
/**
* 用于修复semi的package.json导出的配置问题
*/
fixSemi: boolean;
}
export const defineConfig = (
config: VitestConfig,
otherConfig?: OtherConfig,
): UserConfig => {
const { dirname, preset, ...userVitestConfig } = config;
if (typeof dirname !== 'string') {
throw new Error('define VitestConfig need a dirname.');
}
const baseConfig = calBasePreset(preset);
if (otherConfig?.fixSemi) {
const alias = [
{
find: /^@douyinfe\/semi-ui$/,
replacement: '@douyinfe/semi-ui/lib/es',
},
{
find: /^@douyinfe\/semi-foundation$/,
replacement: '@douyinfe/semi-foundation/lib/es',
},
{
find: 'lottie-web',
replacement: resolve(__dirname, './tsc-only.ts'),
},
];
if (Array.isArray(userVitestConfig.test?.alias)) {
alias.push(...userVitestConfig.test.alias);
} else if (typeof userVitestConfig.test?.alias === 'object') {
alias.push(
...Object.entries(userVitestConfig.test.alias).map(([key, value]) => ({
find: key,
replacement: value,
})),
);
}
userVitestConfig.test = {
...userVitestConfig.test,
alias,
};
}
return mergeConfig(baseConfig, userVitestConfig);
};

View File

@@ -0,0 +1,6 @@
require('sucrase/register/ts');
process.env.VITE_CJS_IGNORE_WARNING = true;
const { defineConfig } = require('./define-config');
module.exports = { defineConfig };

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { coverageConfigDefaults, type UserConfig } from 'vitest/config';
import tsconfigPaths from 'vite-tsconfig-paths';
export const defaultVitestConfig: UserConfig = {
plugins: [tsconfigPaths()],
resolve: {
// 优先识别 main如果没有配置 main则识别 module
mainFields: ['main', 'module', 'exports'],
},
server: {
hmr: {
port: undefined,
},
},
test: {
testTimeout: 10 * 1000,
pool: 'forks',
poolOptions: {
forks: {
maxForks: 32,
minForks: 1,
},
},
sequence: {
// vitest 2.0之后,所有钩子默认串行运行
hooks: 'parallel',
},
globals: true,
mockReset: false,
silent: process.env.CI === 'true',
coverage: {
// 逐步对各包开启
all: false,
include: ['src/**/*.ts', 'src/**/*.tsx'],
exclude: coverageConfigDefaults.exclude,
provider: 'v8',
reporter: ['cobertura', 'text', 'html', 'clover', 'json', 'json-summary'],
},
},
};

View File

@@ -0,0 +1,21 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { mergeConfig } from 'vitest/config';
import { defaultVitestConfig } from './preset-default';
export const nodePreset = mergeConfig(defaultVitestConfig, {});

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { mergeConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
import { defaultVitestConfig } from './preset-default';
export const webPreset = mergeConfig(defaultVitestConfig, {
plugins: [react()],
test: {
environment: 'happy-dom',
framework: {
hmr: 'page',
},
},
});

View File

@@ -0,0 +1,17 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// TODO: should be remove

View File

@@ -0,0 +1,19 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "./tsconfig.json",
"compilerOptions": {
"types": [],
"rootDir": "./src",
"outDir": "dist",
"tsBuildInfoFile": "dist/tsconfig.build.tsbuildinfo"
},
"include": ["./src/tsc-only.ts"],
"references": [
{
"path": "../eslint-config/tsconfig.build.json"
},
{
"path": "../ts-config/tsconfig.build.json"
}
]
}

View File

@@ -0,0 +1,12 @@
{
"extends": "@coze-arch/ts-config/tsconfig.node.json",
"compilerOptions": {
"rootDir": "./src",
"emitDeclarationOnly": true,
"moduleResolution": "NodeNext",
"allowImportingTsExtensions": true,
"outDir": "dist",
"types": ["vitest/globals"]
},
"include": ["src"]
}