-
-
Notifications
You must be signed in to change notification settings - Fork 99
Expand file tree
/
Copy pathvitest.config.ts
More file actions
128 lines (109 loc) · 3.2 KB
/
vitest.config.ts
File metadata and controls
128 lines (109 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { defineConfig } from 'vitest/config'
import YAML from 'yaml'
const ROOT_DIR = path.dirname(fileURLToPath(new URL(import.meta.url)))
const WORKSPACE_FILE = path.resolve(ROOT_DIR, 'pnpm-workspace.yaml')
const CONFIG_FILENAMES = [
'vitest.config.ts',
'vitest.config.mts',
'vitest.config.cts',
'vitest.config.js',
'vitest.config.cjs',
'vitest.config.mjs',
] as const
const BACKSLASH_RE = /\\/g
const LEADING_DOT_SLASH_RE = /^\.\//
const GLOB_CHAR_RE = /[*?[{]/
const TRAILING_SLASHES_RE = /\/+$/
function extractBaseDirFromGlob(pattern: string): string | null {
if (!pattern) {
return null
}
const normalized = pattern
.replace(BACKSLASH_RE, '/')
.replace(LEADING_DOT_SLASH_RE, '')
const globIndex = normalized.search(GLOB_CHAR_RE)
const base = globIndex === -1
? normalized
: normalized.slice(0, globIndex)
const cleaned = base.replace(TRAILING_SLASHES_RE, '')
return cleaned || null
}
function loadProjectRootsFromWorkspace(): string[] {
if (!fs.existsSync(WORKSPACE_FILE)) {
return []
}
try {
const workspaceContent = fs.readFileSync(WORKSPACE_FILE, 'utf8')
const workspace = YAML.parse(workspaceContent) ?? {}
const packages: unknown[] = Array.isArray(workspace.packages) ? workspace.packages : []
const roots = packages
.map(entry => typeof entry === 'string' ? entry.trim() : '')
.filter(entry => entry && !entry.startsWith('!'))
.map(extractBaseDirFromGlob)
.filter((entry): entry is string => Boolean(entry))
return roots.length ? [...new Set(roots)] : []
}
catch (error) {
console.warn('[vitest] Failed to parse pnpm-workspace.yaml, no project roots will be used.', error)
return []
}
}
const PROJECT_ROOTS = loadProjectRootsFromWorkspace()
if (!PROJECT_ROOTS.length) {
console.warn('[vitest] No project roots detected. Check pnpm-workspace.yaml to define workspace packages.')
}
function findConfig(basePath: string): string | null {
for (const filename of CONFIG_FILENAMES) {
const candidate = path.join(basePath, filename)
if (fs.existsSync(candidate)) {
return candidate
}
}
return null
}
function resolveProjects(): string[] {
const projects: string[] = []
for (const folder of PROJECT_ROOTS) {
const rootPath = path.resolve(ROOT_DIR, folder)
if (!fs.existsSync(rootPath)) {
continue
}
const rootConfig = findConfig(rootPath)
if (rootConfig) {
projects.push(rootConfig)
}
const entries = fs.readdirSync(rootPath, { withFileTypes: true })
for (const entry of entries) {
if (!entry.isDirectory()) {
continue
}
const projectDir = path.join(rootPath, entry.name)
const configPath = findConfig(projectDir)
if (configPath) {
projects.push(configPath)
}
}
}
return projects
}
const projects = resolveProjects()
export default defineConfig(() => {
return {
test: {
projects,
coverage: {
enabled: true,
skipFull: true,
exclude: [
'**/dist/**',
],
},
forceRerunTriggers: [
'**/{vitest,vite}.config.*/**',
],
},
}
})