2023-12-13 14:14:33 +08:00
|
|
|
|
import path from 'path';
|
2024-05-28 16:36:49 +08:00
|
|
|
|
|
|
|
|
|
import fg from 'fast-glob';
|
|
|
|
|
import fs from 'fs-extra';
|
|
|
|
|
import ts from 'typescript';
|
|
|
|
|
|
|
|
|
|
import { globExcludeFiles, ROOT_PATH } from './constant';
|
2024-05-29 18:01:32 +08:00
|
|
|
|
import { signals } from './stats';
|
2023-09-03 10:59:33 +08:00
|
|
|
|
|
|
|
|
|
export const buildDeclaration = (cwd: string, targetDir: string) => {
|
2024-05-28 16:36:49 +08:00
|
|
|
|
return new Promise<{ exitCode: 1 | 0; messages: string[] }>((resolve, reject) => {
|
|
|
|
|
const localTsConfigPath = path.join(cwd, 'tsconfig.json');
|
|
|
|
|
|
|
|
|
|
// 读取 tsconfig.json 文件路径
|
|
|
|
|
const configPath = fs.existsSync(localTsConfigPath) ? localTsConfigPath : path.join(ROOT_PATH, 'tsconfig.json');
|
|
|
|
|
|
|
|
|
|
// 读取并解析 tsconfig.json
|
|
|
|
|
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
|
|
|
|
|
|
|
|
if (configFile.error) {
|
|
|
|
|
const message = ts.flattenDiagnosticMessageText(configFile.error.messageText, '\n');
|
|
|
|
|
return reject(`Error reading tsconfig.json: ${message}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 解析 tsconfig.json 配置
|
|
|
|
|
const parsedCommandLine = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
|
|
|
|
|
parsedCommandLine.options.paths = {};
|
|
|
|
|
|
|
|
|
|
// 更新编译选项,设置输出目录为 lib,启用声明文件生成
|
|
|
|
|
parsedCommandLine.options.outDir = path.join(cwd, targetDir);
|
|
|
|
|
parsedCommandLine.options.declaration = true;
|
|
|
|
|
parsedCommandLine.options.emitDeclarationOnly = true;
|
|
|
|
|
|
|
|
|
|
parsedCommandLine.fileNames = fg.globSync(['src/**/*.{ts,tsx}', ...globExcludeFiles], { cwd, absolute: true });
|
|
|
|
|
parsedCommandLine.options.rootDir = path.join(cwd, 'src');
|
|
|
|
|
|
|
|
|
|
// 编译
|
|
|
|
|
const program = ts.createProgram(parsedCommandLine.fileNames, parsedCommandLine.options);
|
|
|
|
|
const emitResult = program.emit();
|
|
|
|
|
|
|
|
|
|
// 处理编译错误
|
|
|
|
|
const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
|
|
|
|
const messages = [];
|
|
|
|
|
allDiagnostics.forEach((diagnostic) => {
|
2024-05-29 18:01:32 +08:00
|
|
|
|
if (diagnostic.file) {
|
|
|
|
|
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
|
|
|
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
|
|
|
|
signals.emit('build:errors', `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
|
|
|
|
console.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
|
|
|
|
} else {
|
|
|
|
|
signals.emit('build:errors', ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
|
|
|
|
|
console.error(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
|
2024-05-28 16:36:49 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const exitCode = emitResult.emitSkipped ? 1 : 0;
|
|
|
|
|
resolve({ exitCode, messages });
|
2023-09-03 10:59:33 +08:00
|
|
|
|
});
|
|
|
|
|
};
|