Skip to content

Commit fd140b4

Browse files
wewellljaysoo
authored andcommitted
fix(bundling): skip unnecessary type-check in TS Solution Setup when skipTypeCheck is true (#34493)
## Current Behavior In TS Solution Setup, the esbuild executor forces `runTypeCheck` even when `skipTypeCheck: true` and `declaration: false`, due to the `|| options.isTsSolutionSetup` condition in `esbuild.impl.ts` (lines 139-140 and 195). When `declaration: false`, this type check runs in `noEmit` mode with `ignoreDiagnostics: true` — making it **completely pointless** (no declarations emitted, no diagnostics reported). Its only observable effect is writing a poisoned 19-byte tsbuildinfo file that causes race conditions with `tsc --build`. ## Expected Behavior When `skipTypeCheck: true` and `declaration: false`, the esbuild executor should not run type checking at all. The `isTsSolutionSetup` override should only force type checking when declarations actually need to be generated. ## Fix ### Primary: Skip unnecessary type check (`esbuild.impl.ts`) ```diff // Non-watch mode (line 195) - if (!options.skipTypeCheck || options.isTsSolutionSetup) { + if (!options.skipTypeCheck || (options.isTsSolutionSetup && options.declaration)) { // Watch mode (lines 139-140) - options.isTsSolutionSetup + (options.isTsSolutionSetup && options.declaration) ``` Only force type checking in TS Solution Setup when declarations need to be generated. This eliminates the pointless type check entirely. ### Defense-in-depth: Prevent tsbuildinfo in `noEmit` mode (`run-type-check.ts`) ```diff - : { noEmit: true }; + : { noEmit: true, composite: false }; ``` Setting `composite: false` alongside `noEmit: true` prevents TypeScript from writing tsbuildinfo files, protecting against this class of bug from any caller of `runTypeCheck`. ## Why This is Safe | Scenario | Before | After | |----------|--------|-------| | `skipTypeCheck: false`, `declaration: false`, `isTsSolutionSetup: true` | Runs type check (noEmit) | Still runs (`!false \|\| ...` = true) | | `skipTypeCheck: false`, `declaration: true`, `isTsSolutionSetup: true` | Runs type check (emitDeclarationOnly) | Still runs | | `skipTypeCheck: true`, `declaration: true`, `isTsSolutionSetup: true` | normalize.ts overrides skipTypeCheck to false; runs type check | Still runs (same normalization) | | **`skipTypeCheck: true`, `declaration: false`, `isTsSolutionSetup: true`** | **Runs pointless type check (noEmit + ignoreDiagnostics), writes poisoned tsbuildinfo** | **Skipped entirely** | The only behavior change is in the last row — the case where the type check was doing nothing useful but causing harm. ## Related Issue(s) Fixes #34492 --------- Co-authored-by: Jack Hsu <jack.hsu@gmail.com> (cherry picked from commit bdeeb03)
1 parent 72a4ba3 commit fd140b4

2 files changed

Lines changed: 6 additions & 3 deletions

File tree

packages/esbuild/src/executors/esbuild/esbuild.impl.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export async function* esbuildExecutor(
137137
build.onEnd(async (result: esbuild.BuildResult) => {
138138
if (
139139
!options.skipTypeCheck ||
140-
options.isTsSolutionSetup
140+
(options.isTsSolutionSetup && options.declaration)
141141
) {
142142
const { errors } = await runTypeCheck(
143143
options,
@@ -192,7 +192,10 @@ export async function* esbuildExecutor(
192192
);
193193
} else {
194194
// Run type-checks first and bail if they don't pass.
195-
if (!options.skipTypeCheck || options.isTsSolutionSetup) {
195+
if (
196+
!options.skipTypeCheck ||
197+
(options.isTsSolutionSetup && options.declaration)
198+
) {
196199
const { errors } = await runTypeCheck(options, context);
197200
if (errors.length > 0) {
198201
yield { success: false };

packages/js/src/utils/typescript/run-type-check.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ async function setupTypeScript(options: TypeCheckOptions) {
140140
? options.outDir.replace(projectRoot, '')
141141
: undefined,
142142
}
143-
: { noEmit: true };
143+
: { noEmit: true, composite: false };
144144

145145
const compilerOptions = {
146146
...config.options,

0 commit comments

Comments
 (0)