diff --git a/packages/js/src/executors/tsc/tsc.impl.ts b/packages/js/src/executors/tsc/tsc.impl.ts index 0340a6d88ce6e..c871385d58aa4 100644 --- a/packages/js/src/executors/tsc/tsc.impl.ts +++ b/packages/js/src/executors/tsc/tsc.impl.ts @@ -144,22 +144,6 @@ export async function* tscExecutor( assets: _options.assets, }); - if (options.watch) { - const disposeWatchAssetChanges = - await assetHandler.watchAndProcessOnAssetChange(); - const disposePackageJsonChanges = await watchForSingleFileChanges( - join(context.root, projectRoot), - 'package.json', - () => updatePackageJson(options, context, target, dependencies) - ); - const handleTermination = async () => { - await disposeWatchAssetChanges(); - await disposePackageJsonChanges(); - }; - process.on('SIGINT', () => handleTermination()); - process.on('SIGTERM', () => handleTermination()); - } - const tsCompilationOptions = createTypeScriptCompilationOptions( options, context @@ -175,7 +159,7 @@ export async function* tscExecutor( tsCompilationOptions.rootDir = '.'; } - return yield* compileTypeScriptFiles( + const typescriptCompilation = compileTypeScriptFiles( options, tsCompilationOptions, async () => { @@ -188,6 +172,26 @@ export async function* tscExecutor( ); } ); + + if (options.watch) { + const disposeWatchAssetChanges = + await assetHandler.watchAndProcessOnAssetChange(); + const disposePackageJsonChanges = await watchForSingleFileChanges( + join(context.root, projectRoot), + 'package.json', + () => updatePackageJson(options, context, target, dependencies) + ); + const handleTermination = async (exitCode: number) => { + await disposeWatchAssetChanges(); + await disposePackageJsonChanges(); + await typescriptCompilation.close(); + process.exit(exitCode); + }; + process.on('SIGINT', () => handleTermination(128 + 2)); + process.on('SIGTERM', () => handleTermination(128 + 15)); + } + + return yield* typescriptCompilation.iterator; } export default tscExecutor; diff --git a/packages/js/src/utils/typescript/compile-typescript-files.ts b/packages/js/src/utils/typescript/compile-typescript-files.ts index 3c5c68e8c2df4..1dde8e35f840c 100644 --- a/packages/js/src/utils/typescript/compile-typescript-files.ts +++ b/packages/js/src/utils/typescript/compile-typescript-files.ts @@ -16,33 +16,58 @@ function getErrorCountFromMessage(messageText: string) { return Number.parseInt(ERROR_COUNT_REGEX.exec(messageText)[1]); } -export async function* compileTypeScriptFiles( +export interface TypescriptCompilationResult { + success: boolean; + outfile: string; +} + +export function compileTypeScriptFiles( normalizedOptions: NormalizedExecutorOptions, tscOptions: TypeScriptCompilationOptions, postCompilationCallback: () => void | Promise -) { +): { + iterator: AsyncIterable; + close: () => void | Promise; +} { const getResult = (success: boolean) => ({ success, outfile: normalizedOptions.mainOutputPath, }); - return yield* createAsyncIterable<{ success: boolean; outfile: string }>( - async ({ next, done }) => { - if (normalizedOptions.watch) { - compileTypeScriptWatcher(tscOptions, async (d: Diagnostic) => { - if (d.code === TYPESCRIPT_FOUND_N_ERRORS_WATCHING_FOR_FILE_CHANGES) { - await postCompilationCallback(); - next( - getResult(getErrorCountFromMessage(d.messageText as string) === 0) - ); - } - }); - } else { - const { success } = compileTypeScript(tscOptions); - await postCompilationCallback(); - next(getResult(success)); - done(); + let tearDown: (() => void) | undefined; + + return { + iterator: createAsyncIterable( + async ({ next, done }) => { + if (normalizedOptions.watch) { + const host = compileTypeScriptWatcher( + tscOptions, + async (d: Diagnostic) => { + if ( + d.code === TYPESCRIPT_FOUND_N_ERRORS_WATCHING_FOR_FILE_CHANGES + ) { + await postCompilationCallback(); + next( + getResult( + getErrorCountFromMessage(d.messageText as string) === 0 + ) + ); + } + } + ); + + tearDown = () => { + host.close(); + done(); + }; + } else { + const { success } = compileTypeScript(tscOptions); + await postCompilationCallback(); + next(getResult(success)); + done(); + } } - } - ); + ), + close: () => tearDown?.(), + }; }