Skip to content

Commit 2a16350

Browse files
refactor: optimize dts logs and show codeblocks of tsc diagnostics (#847)
Co-authored-by: Wei <[email protected]>
1 parent 9c5ea00 commit 2a16350

File tree

3 files changed

+51
-35
lines changed

3 files changed

+51
-35
lines changed

packages/plugin-dts/src/apiExtractor.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ import { join, relative } from 'node:path';
22
import {
33
Extractor,
44
ExtractorConfig,
5+
ExtractorLogLevel,
56
type ExtractorResult,
67
} from '@microsoft/api-extractor';
78
import { logger } from '@rsbuild/core';
89
import color from 'picocolors';
910
import type { DtsEntry } from './index';
1011
import { addBannerAndFooter, getTimeCost } from './utils';
1112

13+
const logPrefixApiExtractor = color.dim('[api-extractor]');
14+
1215
export type BundleOptions = {
1316
name: string;
1417
cwd: string;
@@ -66,6 +69,20 @@ export async function bundleDts(options: BundleOptions): Promise<void> {
6669
extractorConfig,
6770
{
6871
localBuild: true,
72+
messageCallback(message) {
73+
/**
74+
* message.text is readonly, we can not add prefix
75+
* do not log below two cases
76+
* 1. Analysis will use the bundled TypeScript version 5.7.3
77+
* 2. The target project appears to use TypeScript 5.8.2 which is newer than the bundled compiler engine; consider upgrading API Extractor.
78+
*/
79+
if (
80+
message.messageId === 'console-compiler-version-notice' ||
81+
message.messageId === 'console-preamble'
82+
) {
83+
message.logLevel = ExtractorLogLevel.None;
84+
}
85+
},
6986
},
7087
);
7188

@@ -75,12 +92,12 @@ export async function bundleDts(options: BundleOptions): Promise<void> {
7592

7693
await addBannerAndFooter(untrimmedFilePath, banner, footer);
7794

78-
logger.info(
79-
`bundle declaration files succeeded: ${color.cyan(untrimmedFilePath)} in ${getTimeCost(start)} ${color.gray(`(${name})`)}`,
95+
logger.ready(
96+
`declaration files bundled successfully: ${color.cyan(relative(cwd, untrimmedFilePath))} in ${getTimeCost(start)} ${color.gray(`(${name})`)}`,
8097
);
8198
}),
8299
);
83100
} catch (e) {
84-
throw new Error(`API Extractor Error:\n ${e}`);
101+
throw new Error(`${logPrefixApiExtractor} ${e}`);
85102
}
86103
}

packages/plugin-dts/src/dts.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ export async function generateDts(data: DtsGenOptions): Promise<void> {
126126
extension: false,
127127
},
128128
} = data;
129-
logger.start(`generating declaration files... ${color.gray(`(${name})`)}`);
129+
if (!isWatch) {
130+
logger.start(`generating declaration files... ${color.gray(`(${name})`)}`);
131+
}
130132

131133
const { options: rawCompilerOptions, fileNames } = tsConfigResult;
132134

packages/plugin-dts/src/tsc.ts

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@ import { logger } from '@rsbuild/core';
22
import color from 'picocolors';
33
import ts from 'typescript';
44
import type { DtsRedirect } from './index';
5-
import { getFileLoc, getTimeCost, processDtsFiles } from './utils';
5+
import { getTimeCost, processDtsFiles } from './utils';
66

7-
const logPrefix = color.dim('[tsc]');
7+
const logPrefixTsc = color.dim('[tsc]');
8+
9+
const formatHost: ts.FormatDiagnosticsHost = {
10+
getCanonicalFileName: (path) => path,
11+
getCurrentDirectory: ts.sys.getCurrentDirectory,
12+
getNewLine: () => ts.sys.newLine,
13+
};
814

915
export type EmitDtsOptions = {
1016
name: string;
@@ -22,7 +28,6 @@ export type EmitDtsOptions = {
2228
async function handleDiagnosticsAndProcessFiles(
2329
diagnostics: readonly ts.Diagnostic[],
2430
configPath: string,
25-
host: ts.CompilerHost,
2631
bundle: boolean,
2732
declarationDir: string,
2833
dtsExtension: string,
@@ -35,11 +40,10 @@ async function handleDiagnosticsAndProcessFiles(
3540
const diagnosticMessages: string[] = [];
3641

3742
for (const diagnostic of diagnostics) {
38-
const fileLoc = getFileLoc(diagnostic, configPath);
39-
const message = `${fileLoc} - ${color.red('error')} ${color.gray(`TS${diagnostic.code}:`)} ${ts.flattenDiagnosticMessageText(
40-
diagnostic.messageText,
41-
host.getNewLine(),
42-
)}`;
43+
const message = ts.formatDiagnosticsWithColorAndContext(
44+
[diagnostic],
45+
formatHost,
46+
);
4347
diagnosticMessages.push(message);
4448
}
4549

@@ -56,7 +60,7 @@ async function handleDiagnosticsAndProcessFiles(
5660

5761
if (diagnosticMessages.length) {
5862
for (const message of diagnosticMessages) {
59-
logger.error(logPrefix, message);
63+
logger.error(logPrefixTsc, message);
6064
}
6165

6266
throw new Error(
@@ -100,22 +104,11 @@ export async function emitDts(
100104
};
101105

102106
const createProgram = ts.createSemanticDiagnosticsBuilderProgram;
103-
const formatHost: ts.FormatDiagnosticsHost = {
104-
getCanonicalFileName: (path) => path,
105-
getCurrentDirectory: ts.sys.getCurrentDirectory,
106-
getNewLine: () => ts.sys.newLine,
107-
};
108107

109108
const reportDiagnostic = (diagnostic: ts.Diagnostic) => {
110-
const fileLoc = getFileLoc(diagnostic, configPath);
111-
112109
logger.error(
113-
logPrefix,
114-
`${fileLoc} - ${color.red('error')} ${color.gray(`TS${diagnostic.code}:`)}`,
115-
ts.flattenDiagnosticMessageText(
116-
diagnostic.messageText,
117-
formatHost.getNewLine(),
118-
),
110+
logPrefixTsc,
111+
ts.formatDiagnosticsWithColorAndContext([diagnostic], formatHost),
119112
);
120113
};
121114

@@ -133,16 +126,16 @@ export async function emitDts(
133126
// 6031: File change detected. Starting incremental compilation...
134127
// 6032: Starting compilation in watch mode...
135128
if (diagnostic.code === 6031 || diagnostic.code === 6032) {
136-
logger.info(logPrefix, message);
129+
logger.info(logPrefixTsc, message);
137130
}
138131

139132
// 6194: 0 errors or 2+ errors!
140133
if (diagnostic.code === 6194) {
141134
if (errorCount === 0 || !errorCount) {
142-
logger.info(logPrefix, message);
135+
logger.info(logPrefixTsc, message);
143136
onComplete(true);
144137
} else {
145-
logger.error(logPrefix, message);
138+
logger.error(logPrefixTsc, message);
146139
}
147140
await processDtsFiles(
148141
bundle,
@@ -158,7 +151,7 @@ export async function emitDts(
158151

159152
// 6193: 1 error
160153
if (diagnostic.code === 6193) {
161-
logger.error(logPrefix, message);
154+
logger.error(logPrefixTsc, message);
162155
await processDtsFiles(
163156
bundle,
164157
declarationDir,
@@ -198,7 +191,6 @@ export async function emitDts(
198191
await handleDiagnosticsAndProcessFiles(
199192
allDiagnostics,
200193
configPath,
201-
host,
202194
bundle,
203195
declarationDir,
204196
dtsExtension,
@@ -232,7 +224,6 @@ export async function emitDts(
232224
await handleDiagnosticsAndProcessFiles(
233225
allDiagnostics,
234226
configPath,
235-
host,
236227
bundle,
237228
declarationDir,
238229
dtsExtension,
@@ -284,9 +275,15 @@ export async function emitDts(
284275
}
285276
}
286277

287-
logger.ready(
288-
`declaration files generated in ${getTimeCost(start)} ${color.gray(`(${name})`)}`,
289-
);
278+
if (bundle) {
279+
logger.info(
280+
`declaration files prepared in ${getTimeCost(start)} ${color.gray(`(${name})`)}`,
281+
);
282+
} else {
283+
logger.ready(
284+
`declaration files generated in ${getTimeCost(start)} ${color.gray(`(${name})`)}`,
285+
);
286+
}
290287
} else {
291288
// watch mode, can also deal with incremental build
292289
if (!build) {

0 commit comments

Comments
 (0)