diff --git a/packages/plugin-dts/src/apiExtractor.ts b/packages/plugin-dts/src/apiExtractor.ts index 07c814806..92dba286a 100644 --- a/packages/plugin-dts/src/apiExtractor.ts +++ b/packages/plugin-dts/src/apiExtractor.ts @@ -17,6 +17,7 @@ export type BundleOptions = { dtsEntry: DtsEntry[]; tsconfigPath?: string; bundledPackages?: string[]; + resolveWatchCallback?: () => void; }; export async function bundleDts(options: BundleOptions): Promise { @@ -40,6 +41,7 @@ export async function bundleDts(options: BundleOptions): Promise { dtsEntry, tsconfigPath = 'tsconfig.json', bundledPackages = [], + resolveWatchCallback, } = options; try { await Promise.all( @@ -102,6 +104,8 @@ export async function bundleDts(options: BundleOptions): Promise { ); }), ); + + resolveWatchCallback?.(); } catch (e) { throw new Error(`${logPrefixApiExtractor} ${e}`); } diff --git a/packages/plugin-dts/src/dts.ts b/packages/plugin-dts/src/dts.ts index 41818d836..d8031e842 100644 --- a/packages/plugin-dts/src/dts.ts +++ b/packages/plugin-dts/src/dts.ts @@ -200,33 +200,44 @@ export async function generateDts(data: DtsGenOptions): Promise { .filter(Boolean) as Required[]; } - const bundleDtsIfNeeded = async () => { - if (bundle === true) { - const { bundleDts } = await import('./apiExtractor'); - await bundleDts({ - name, + const bundleDtsFiles = async (resolveWatchCallback?: () => void) => { + const { bundleDts } = await import('./apiExtractor'); + await bundleDts({ + name, + cwd, + distPath: dtsEmitPath, + dtsEntry: dtsEntries, + tsconfigPath, + dtsExtension, + banner, + footer, + bundledPackages: calcBundledPackages({ + autoExternal, cwd, - distPath: dtsEmitPath, - dtsEntry: dtsEntries, - tsconfigPath, - dtsExtension, - banner, - footer, - bundledPackages: calcBundledPackages({ - autoExternal, - cwd, - userExternals, - }), - }); - } + userExternals, + }), + resolveWatchCallback, + }); }; - const onComplete = async (isSuccess: boolean) => { - if (isSuccess) { - await bundleDtsIfNeeded(); - } + let resolveWatchCallback: () => void; + + const bundleDtsFunc = async () => { + await bundleDtsFiles(resolveWatchCallback); + }; + + const resolveWatch = () => { + resolveWatchCallback(); }; + const dtsCompletion = new Promise((resolve) => { + if (isWatch) { + resolveWatchCallback = resolve; + } else { + resolve(); + } + }); + await emitDts( { name, @@ -240,15 +251,18 @@ export async function generateDts(data: DtsGenOptions): Promise { banner, footer, }, - onComplete, + bundleDtsFunc, + resolveWatch, bundle, isWatch, build, ); - if (!isWatch) { - await bundleDtsIfNeeded(); + if (!isWatch && bundle) { + await bundleDtsFiles(); } + + await dtsCompletion; } process.on('message', async (data: DtsGenOptions) => { diff --git a/packages/plugin-dts/src/tsc.ts b/packages/plugin-dts/src/tsc.ts index c4fa46dac..6d5ff3c8b 100644 --- a/packages/plugin-dts/src/tsc.ts +++ b/packages/plugin-dts/src/tsc.ts @@ -2,7 +2,7 @@ import { logger } from '@rsbuild/core'; import color from 'picocolors'; import ts from 'typescript'; import type { DtsRedirect } from './index'; -import { getTimeCost, processDtsFiles } from './utils'; +import { getTimeCost, processBundlelessDtsFiles } from './utils'; const logPrefixTsc = color.dim('[tsc]'); @@ -47,16 +47,17 @@ async function handleDiagnosticsAndProcessFiles( diagnosticMessages.push(message); } - await processDtsFiles( - bundle, - declarationDir, - dtsExtension, - redirect, - configPath, - rootDir, - banner, - footer, - ); + if (!bundle) { + await processBundlelessDtsFiles( + declarationDir, + dtsExtension, + redirect, + configPath, + rootDir, + banner, + footer, + ); + } if (diagnosticMessages.length) { for (const message of diagnosticMessages) { @@ -71,7 +72,8 @@ async function handleDiagnosticsAndProcessFiles( export async function emitDts( options: EmitDtsOptions, - onComplete: (isSuccess: boolean) => void, + bundleDtsFunc: () => Promise, + resolveWatch: () => void, bundle = false, isWatch = false, build = false, @@ -112,7 +114,7 @@ export async function emitDts( ); }; - const reportWatchStatusChanged: ts.WatchStatusReporter = async ( + const reportWatchStatusChanged: ts.WatchStatusReporter = ( diagnostic: ts.Diagnostic, _newLine: string, _options: ts.CompilerOptions, @@ -129,39 +131,53 @@ export async function emitDts( logger.info(logPrefixTsc, message); } + const hasError = errorCount && errorCount > 0; + // 6194: 0 errors or 2+ errors! if (diagnostic.code === 6194) { - if (errorCount === 0 || !errorCount) { + if (!hasError) { logger.info(logPrefixTsc, message); - onComplete(true); } else { logger.error(logPrefixTsc, message); } - await processDtsFiles( - bundle, - declarationDir, - dtsExtension, - redirect, - configPath, - rootDir, - banner, - footer, - ); + + if (bundle) { + if (hasError) { + resolveWatch(); + } else { + bundleDtsFunc(); + } + } else { + processBundlelessDtsFiles( + declarationDir, + dtsExtension, + redirect, + configPath, + rootDir, + banner, + footer, + resolveWatch, + ); + } } // 6193: 1 error if (diagnostic.code === 6193) { logger.error(logPrefixTsc, message); - await processDtsFiles( - bundle, - declarationDir, - dtsExtension, - redirect, - configPath, - rootDir, - banner, - footer, - ); + if (bundle) { + bundleDtsFunc(); + } else { + processBundlelessDtsFiles( + declarationDir, + dtsExtension, + redirect, + configPath, + rootDir, + banner, + footer, + resolveWatch, + ); + } } }; @@ -306,16 +322,17 @@ export async function emitDts( solutionBuilder.build(); - await processDtsFiles( - bundle, - declarationDir, - dtsExtension, - redirect, - configPath, - rootDir, - banner, - footer, - ); + if (!bundle) { + await processBundlelessDtsFiles( + declarationDir, + dtsExtension, + redirect, + configPath, + rootDir, + banner, + footer, + ); + } if (errorNumber > 0) { throw new Error( diff --git a/packages/plugin-dts/src/utils.ts b/packages/plugin-dts/src/utils.ts index 6ba178d84..1696a337a 100644 --- a/packages/plugin-dts/src/utils.ts +++ b/packages/plugin-dts/src/utils.ts @@ -371,8 +371,7 @@ export async function redirectDtsImports( } } -export async function processDtsFiles( - bundle: boolean, +export async function processBundlelessDtsFiles( dir: string, dtsExtension: string, redirect: DtsRedirect, @@ -380,11 +379,8 @@ export async function processDtsFiles( rootDir: string, banner?: string, footer?: string, + resolveWatch?: () => void, ): Promise { - if (bundle) { - return; - } - let matchPath: MatchPath | undefined; if (redirect.path || redirect.extension) { @@ -428,6 +424,8 @@ export async function processDtsFiles( } }), ); + + resolveWatch?.(); } export function processSourceEntry(