feat: build支持skipExtraCheck和skipEmitDiagnostics参数,用于项目中快速检查web
This commit is contained in:
parent
23abd05811
commit
81e000fa07
|
|
@ -34,6 +34,8 @@ interface CustomDiagnostic {
|
|||
export type CompileOptions = {
|
||||
project?: string;
|
||||
noEmit?: boolean;
|
||||
skipExtraCheck?: boolean;
|
||||
skipEmitDiagnostics?: boolean;
|
||||
};
|
||||
/**
|
||||
* 执行自定义检查
|
||||
|
|
|
|||
|
|
@ -175,6 +175,14 @@ const isIdentifierWithSymbol = (node, symbol, typeChecker) => {
|
|||
* @returns boolean
|
||||
*/
|
||||
const isFileInCheckScope = (pwd, fileName, customConfig) => {
|
||||
const isUpperFile = path.relative(pwd, fileName).startsWith('..');
|
||||
if (isUpperFile) {
|
||||
return false;
|
||||
}
|
||||
const inNodeModules = fileName.includes('node_modules');
|
||||
if (inNodeModules) {
|
||||
return false;
|
||||
}
|
||||
const patterns = customConfig.context?.filePatterns || ['**/*.ts', '**/*.tsx'];
|
||||
const normalizedFileName = path.normalize(path.relative(pwd, fileName)).replace(/\\/g, '/');
|
||||
for (const pattern of patterns) {
|
||||
|
|
@ -206,13 +214,14 @@ function parseArgs(pargs) {
|
|||
const args = pargs.slice(2);
|
||||
const options = {
|
||||
project: 'tsconfig.json',
|
||||
noEmit: false
|
||||
noEmit: false,
|
||||
skipExtraCheck: false
|
||||
};
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] === '-p' || args[i] === '--project') {
|
||||
if (i + 1 < args.length) {
|
||||
options.project = args[i + 1];
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
console.error('error: option \'-p, --project\' argument missing');
|
||||
|
|
@ -222,6 +231,12 @@ function parseArgs(pargs) {
|
|||
else if (args[i] === '--noEmit') {
|
||||
options.noEmit = true;
|
||||
}
|
||||
else if (args[i] === '--skipExtraCheck') {
|
||||
options.skipExtraCheck = true;
|
||||
}
|
||||
else if (args[i] === '--skipEmitDiagnostics') {
|
||||
options.skipEmitDiagnostics = true;
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
|
@ -1017,9 +1032,6 @@ function performCustomChecks(pwd, program, typeChecker, customConfig) {
|
|||
const checkIndirectCalls = () => {
|
||||
// 使用之前收集的调用列表,避免重复遍历
|
||||
for (const [sourceFile, callsToCheck] of callsToCheckByFile.entries()) {
|
||||
if (sourceFile.isDeclarationFile || sourceFile.fileName.includes('node_modules')) {
|
||||
continue;
|
||||
}
|
||||
for (const node of callsToCheck) {
|
||||
if (!ts.isCallExpression(node))
|
||||
continue;
|
||||
|
|
@ -2532,7 +2544,7 @@ function performCustomChecks(pwd, program, typeChecker, customConfig) {
|
|||
};
|
||||
// 信息收集
|
||||
for (const sourceFile of program.getSourceFiles()) {
|
||||
if (sourceFile.isDeclarationFile || sourceFile.fileName.includes('node_modules')) {
|
||||
if (sourceFile.isDeclarationFile) {
|
||||
continue;
|
||||
}
|
||||
// 文件名是否符合检查范围
|
||||
|
|
@ -2761,30 +2773,55 @@ const compile = (pwd, options) => {
|
|||
// 执行编译
|
||||
emitResult = program.emit();
|
||||
}
|
||||
else {
|
||||
console.log(`${colors.yellow}Emit skipped as per configuration.${colors.reset}`);
|
||||
}
|
||||
// 获取诊断信息
|
||||
const allDiagnostics = [
|
||||
...ts.getPreEmitDiagnostics(program),
|
||||
...emitResult.diagnostics,
|
||||
];
|
||||
// 输出诊断信息
|
||||
allDiagnostics.forEach((diagnostic, index) => printDiagnostic(pwd, diagnostic, index));
|
||||
let index = 0;
|
||||
let errCount = 0;
|
||||
let warnCount = 0;
|
||||
if (!options.skipEmitDiagnostics) {
|
||||
allDiagnostics.forEach((diagnostic) => {
|
||||
if (options.skipExtraCheck) {
|
||||
const fileName = diagnostic.file ? path.resolve(diagnostic.file.fileName) : null;
|
||||
if (fileName && !isFileInCheckScope(pwd, fileName, customConfig)) {
|
||||
return; // 跳过非工作目录下的文件诊断
|
||||
}
|
||||
}
|
||||
const level = getDiagnosticLevel(diagnostic);
|
||||
if (level === 'error') {
|
||||
errCount++;
|
||||
}
|
||||
else if (level === 'warning') {
|
||||
warnCount++;
|
||||
}
|
||||
printDiagnostic(pwd, diagnostic, index);
|
||||
index++;
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.log(`${colors.yellow}Emit diagnostics skipped as per configuration.${colors.reset}`);
|
||||
}
|
||||
// 输出编译统计
|
||||
const errorCount = allDiagnostics.filter(d => d.category === ts.DiagnosticCategory.Error).length;
|
||||
const warningCount = allDiagnostics.filter(d => d.category === ts.DiagnosticCategory.Warning).length;
|
||||
if (errorCount > 0 || warningCount > 0) {
|
||||
if (errCount > 0 || warnCount > 0) {
|
||||
if (allDiagnostics.length > 0) {
|
||||
console.log('');
|
||||
}
|
||||
const parts = [];
|
||||
if (errorCount > 0) {
|
||||
parts.push(`${errorCount} error${errorCount !== 1 ? 's' : ''}`);
|
||||
if (errCount > 0) {
|
||||
parts.push(`${errCount} error${errCount !== 1 ? 's' : ''}`);
|
||||
}
|
||||
if (warningCount > 0) {
|
||||
parts.push(`${warningCount} warning${warningCount !== 1 ? 's' : ''}`);
|
||||
if (warnCount > 0) {
|
||||
parts.push(`${warnCount} warning${warnCount !== 1 ? 's' : ''}`);
|
||||
}
|
||||
console.log(`Found ${parts.join(' and ')}.`);
|
||||
}
|
||||
if (errorCount > 0) {
|
||||
if (errCount > 0) {
|
||||
console.log(`${colors.red}Compilation failed due to errors.${colors.reset}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
@ -2821,3 +2858,11 @@ const build = (pwd, args) => {
|
|||
compile(pwd, options);
|
||||
};
|
||||
exports.build = build;
|
||||
function getDiagnosticLevel(diagnostic) {
|
||||
if (diagnostic.category === ts.DiagnosticCategory.Error) {
|
||||
return 'error';
|
||||
}
|
||||
else if (diagnostic.category === ts.DiagnosticCategory.Warning) {
|
||||
return 'warning';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,6 +191,14 @@ const isIdentifierWithSymbol = (
|
|||
* @returns boolean
|
||||
*/
|
||||
const isFileInCheckScope = (pwd: string, fileName: string, customConfig: OakBuildChecksConfig): boolean => {
|
||||
const isUpperFile = path.relative(pwd, fileName).startsWith('..')
|
||||
if (isUpperFile) {
|
||||
return false;
|
||||
}
|
||||
const inNodeModules = fileName.includes('node_modules');
|
||||
if (inNodeModules) {
|
||||
return false;
|
||||
}
|
||||
const patterns = customConfig.context?.filePatterns || ['**/*.ts', '**/*.tsx'];
|
||||
const normalizedFileName = path.normalize(path.relative(pwd, fileName)).replace(/\\/g, '/');
|
||||
for (const pattern of patterns) {
|
||||
|
|
@ -275,6 +283,10 @@ const colors = {
|
|||
export type CompileOptions = {
|
||||
project?: string;
|
||||
noEmit?: boolean;
|
||||
// 忽略非当前工作目录下的文件检查
|
||||
skipExtraCheck?: boolean;
|
||||
// 忽略EmitDiagnostics
|
||||
skipEmitDiagnostics?: boolean;
|
||||
}
|
||||
|
||||
// 解析命令行参数
|
||||
|
|
@ -282,20 +294,25 @@ function parseArgs(pargs: string[]): CompileOptions {
|
|||
const args: string[] = pargs.slice(2);
|
||||
const options: CompileOptions = {
|
||||
project: 'tsconfig.json',
|
||||
noEmit: false
|
||||
noEmit: false,
|
||||
skipExtraCheck: false
|
||||
};
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] === '-p' || args[i] === '--project') {
|
||||
if (i + 1 < args.length) {
|
||||
options.project = args[i + 1];
|
||||
break;
|
||||
i++;
|
||||
} else {
|
||||
console.error('error: option \'-p, --project\' argument missing');
|
||||
process.exit(1);
|
||||
}
|
||||
} else if (args[i] === '--noEmit') {
|
||||
options.noEmit = true;
|
||||
} else if (args[i] === '--skipExtraCheck') {
|
||||
options.skipExtraCheck = true;
|
||||
} else if (args[i] === '--skipEmitDiagnostics') {
|
||||
options.skipEmitDiagnostics = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1269,10 +1286,6 @@ export function performCustomChecks(
|
|||
const checkIndirectCalls = (): void => {
|
||||
// 使用之前收集的调用列表,避免重复遍历
|
||||
for (const [sourceFile, callsToCheck] of callsToCheckByFile.entries()) {
|
||||
if (sourceFile.isDeclarationFile || sourceFile.fileName.includes('node_modules')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const node of callsToCheck) {
|
||||
if (!ts.isCallExpression(node)) continue;
|
||||
if (shouldSkipCheck(node)) continue;
|
||||
|
|
@ -3159,7 +3172,7 @@ export function performCustomChecks(
|
|||
|
||||
// 信息收集
|
||||
for (const sourceFile of program.getSourceFiles()) {
|
||||
if (sourceFile.isDeclarationFile || sourceFile.fileName.includes('node_modules')) {
|
||||
if (sourceFile.isDeclarationFile) {
|
||||
continue;
|
||||
}
|
||||
// 文件名是否符合检查范围
|
||||
|
|
@ -3456,6 +3469,8 @@ const compile = (pwd: string, options: CompileOptions): void => {
|
|||
if (!options.noEmit) {
|
||||
// 执行编译
|
||||
emitResult = program.emit();
|
||||
} else {
|
||||
console.log(`${colors.yellow}Emit skipped as per configuration.${colors.reset}`);
|
||||
}
|
||||
|
||||
// 获取诊断信息
|
||||
|
|
@ -3465,28 +3480,47 @@ const compile = (pwd: string, options: CompileOptions): void => {
|
|||
];
|
||||
|
||||
// 输出诊断信息
|
||||
allDiagnostics.forEach((diagnostic, index) => printDiagnostic(pwd, diagnostic, index));
|
||||
let index = 0;
|
||||
let errCount = 0;
|
||||
let warnCount = 0;
|
||||
if (!options.skipEmitDiagnostics) {
|
||||
allDiagnostics.forEach((diagnostic) => {
|
||||
if (options.skipExtraCheck) {
|
||||
const fileName = diagnostic.file ? path.resolve(diagnostic.file.fileName) : null;
|
||||
if (fileName && !isFileInCheckScope(pwd, fileName, customConfig)) {
|
||||
return; // 跳过非工作目录下的文件诊断
|
||||
}
|
||||
}
|
||||
const level = getDiagnosticLevel(diagnostic);
|
||||
if (level === 'error') {
|
||||
errCount++;
|
||||
} else if (level === 'warning') {
|
||||
warnCount++;
|
||||
}
|
||||
printDiagnostic(pwd, diagnostic, index)
|
||||
index++;
|
||||
});
|
||||
} else {
|
||||
console.log(`${colors.yellow}Emit diagnostics skipped as per configuration.${colors.reset}`);
|
||||
}
|
||||
|
||||
// 输出编译统计
|
||||
const errorCount = allDiagnostics.filter(d => d.category === ts.DiagnosticCategory.Error).length;
|
||||
const warningCount = allDiagnostics.filter(d => d.category === ts.DiagnosticCategory.Warning).length;
|
||||
|
||||
if (errorCount > 0 || warningCount > 0) {
|
||||
if (errCount > 0 || warnCount > 0) {
|
||||
if (allDiagnostics.length > 0) {
|
||||
console.log('');
|
||||
}
|
||||
|
||||
const parts: string[] = [];
|
||||
if (errorCount > 0) {
|
||||
parts.push(`${errorCount} error${errorCount !== 1 ? 's' : ''}`);
|
||||
if (errCount > 0) {
|
||||
parts.push(`${errCount} error${errCount !== 1 ? 's' : ''}`);
|
||||
}
|
||||
if (warningCount > 0) {
|
||||
parts.push(`${warningCount} warning${warningCount !== 1 ? 's' : ''}`);
|
||||
if (warnCount > 0) {
|
||||
parts.push(`${warnCount} warning${warnCount !== 1 ? 's' : ''}`);
|
||||
}
|
||||
console.log(`Found ${parts.join(' and ')}.`);
|
||||
}
|
||||
|
||||
if (errorCount > 0) {
|
||||
if (errCount > 0) {
|
||||
console.log(`${colors.red}Compilation failed due to errors.${colors.reset}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
@ -3526,3 +3560,12 @@ export const build = (pwd: string, args: any[]) => {
|
|||
options.project = configPath;
|
||||
compile(pwd, options);
|
||||
}
|
||||
|
||||
function getDiagnosticLevel(diagnostic: ts.Diagnostic) {
|
||||
if (diagnostic.category === ts.DiagnosticCategory.Error) {
|
||||
return 'error';
|
||||
} else if (diagnostic.category === ts.DiagnosticCategory.Warning) {
|
||||
return 'warning';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue