Merge from vben

This commit is contained in:
xingyu4j
2026-06-26 16:02:30 +08:00
56 changed files with 3937 additions and 3743 deletions

View File

@@ -1,6 +1,7 @@
import type { CAC } from 'cac';
import { execSync } from 'node:child_process';
import { availableParallelism, freemem } from 'node:os';
import { execaCommand } from '@vben/node-utils';
@@ -15,32 +16,49 @@ interface LintCommandOptions {
threads?: number;
}
async function runLint({ format, threads }: LintCommandOptions) {
// process.env.FORCE_COLOR = '3';
const threadsArg = threads ? ` --threads=${threads}` : ` --threads=2`;
/**
* CPU 逻辑核心数阈值 4 核。
* - 小于等于该值:视为低配机器,检查命令串行执行,避免瞬时占用飙升。
*/
const CPU_CORE_THRESHOLD = 4;
if (format) {
await execaCommand(`stylelint "**/*.{vue,css,less,scss}" --cache --fix`, {
stdio: 'inherit',
});
await execaCommand(`oxfmt${threadsArg}`, {
stdio: 'inherit',
});
await execaCommand(`oxlint --fix${threadsArg}`, {
stdio: 'inherit',
});
await execaCommand(`eslint . --cache --fix`, {
stdio: 'inherit',
});
return;
/**
* 可用内存阈值 8 GB。
* 仅当空余内存大于阈值且当前可用内存大于该值时,
* oxfmt / oxlint 默认线程数才提升到 4否则使用 2。
*/
const FREE_MEMORY_THRESHOLD = 8 * 1024 ** 3;
/**
* 串行执行所有命令:一次只运行一个进程。
* 保证一次能看到所有工具的报错(配置低的机器更友好)。
*/
async function runSerial(commands: string[]) {
const failed: string[] = [];
for (const command of commands) {
try {
await execaCommand(command, { stdio: 'inherit' });
} catch {
failed.push(command);
}
}
const subprocesses = [
execaCommand(`oxlint${threadsArg}`, { stdio: 'inherit' }),
execaCommand(`eslint . --cache`, { stdio: 'inherit' }),
execaCommand(`stylelint "**/*.{vue,css,less,scss}" --cache`, {
stdio: 'inherit',
}),
];
if (failed.length > 0) {
throw new Error(
`Lint failed:\n${failed.map((command) => ` - ${command}`).join('\n')}`,
);
}
}
/**
* 并行执行所有命令:同时启动全部进程。
* 任一进程失败时,强制结束其余仍在运行的进程,避免产生遗漏进程。
*/
async function runParallel(commands: string[]) {
const subprocesses = commands.map((command) =>
execaCommand(command, { stdio: 'inherit' }),
);
try {
await Promise.all(subprocesses);
@@ -63,6 +81,46 @@ async function runLint({ format, threads }: LintCommandOptions) {
}
}
async function runLint({ format, threads }: LintCommandOptions) {
// process.env.FORCE_COLOR = '3';
const cpuCores = availableParallelism();
// CPU 核心数充足且可用内存充足时,默认线程数提升到 4否则维持 2
// 用户通过 --threads 显式指定时优先使用其值。
const defaultThreads =
cpuCores > CPU_CORE_THRESHOLD && freemem() > FREE_MEMORY_THRESHOLD ? 4 : 2;
const threadsArg = ` --threads=${threads || defaultThreads}`;
if (format) {
await execaCommand(`stylelint "**/*.{vue,css,less,scss}" --cache --fix`, {
stdio: 'inherit',
});
await execaCommand(`oxfmt${threadsArg}`, {
stdio: 'inherit',
});
await execaCommand(`oxlint --fix --type-aware${threadsArg}`, {
stdio: 'inherit',
});
await execaCommand(`eslint . --cache --fix`, {
stdio: 'inherit',
});
return;
}
const commands = [
`oxfmt --check${threadsArg}`,
`oxlint --type-aware${threadsArg}`,
`eslint . --cache`,
`stylelint "**/*.{vue,css,less,scss}" --cache`,
];
// 低配机器CPU 核心数较少)串行执行,避免多进程并发导致瞬时占用飙升;
// 高配机器并行执行以缩短整体耗时。
await (cpuCores <= CPU_CORE_THRESHOLD
? runSerial(commands)
: runParallel(commands));
}
function defineLintCommand(cac: CAC) {
cac
.command('lint')