Skip to content

Commit 1711edd

Browse files
committed
fix: forward typescript compiler error detail to esbuild
1 parent 02d72a7 commit 1711edd

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

src/plugin.ts

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import chalk from "chalk";
2-
import { Plugin } from "esbuild";
2+
import { PartialMessage, Plugin } from "esbuild";
33
import { existsSync, lstatSync } from "fs";
44
import { resolve } from "path";
55
import ts from "typescript";
@@ -38,14 +38,22 @@ export const dtsPlugin = (opts: DTSPluginOpts = {}) =>
3838
build.onLoad({ filter: /(\.tsx|\.ts)$/ }, async (args) => {
3939
inputFiles.push(args.path);
4040

41+
const errors: PartialMessage[] = [];
42+
4143
compilerHost.getSourceFile(
4244
args.path,
4345
compilerOptions.target ?? ts.ScriptTarget.Latest,
44-
(m) => console.log(m),
46+
(m) => {
47+
errors.push({
48+
detail: m,
49+
});
50+
},
4551
true,
4652
);
4753

48-
return {};
54+
return {
55+
errors,
56+
};
4957
});
5058

5159
build.onEnd(() => {
@@ -65,6 +73,41 @@ export const dtsPlugin = (opts: DTSPluginOpts = {}) =>
6573
);
6674
}
6775

76+
const diagnostics = ts
77+
.getPreEmitDiagnostics(compilerProgram as ts.Program)
78+
.map(
79+
(d) =>
80+
({
81+
text:
82+
typeof d.messageText === "string"
83+
? d.messageText
84+
: d.messageText.messageText,
85+
detail: d,
86+
location: {
87+
file: d.file?.fileName,
88+
namespace: "file",
89+
},
90+
category: d.category,
91+
}) satisfies PartialMessage & {
92+
category: ts.DiagnosticCategory;
93+
},
94+
);
95+
96+
const errors = diagnostics
97+
.filter((d) => d.category === ts.DiagnosticCategory.Error)
98+
.map(({ category: _, ...message }) => message);
99+
100+
const warnings = diagnostics
101+
.filter((d) => d.category === ts.DiagnosticCategory.Warning)
102+
.map(({ category: _, ...message }) => message);
103+
104+
if (errors.length > 0) {
105+
return {
106+
errors,
107+
warnings,
108+
};
109+
}
110+
68111
const startTime = Date.now();
69112
const emitResult = compilerProgram.emit();
70113

@@ -100,6 +143,10 @@ export const dtsPlugin = (opts: DTSPluginOpts = {}) =>
100143
Date.now() - startTime
101144
}ms}`,
102145
);
146+
147+
return {
148+
warnings,
149+
};
103150
});
104151
},
105152
}) as Plugin;

tests/index.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,14 @@ describe("TSConfig extends is resolved", () => {
8989
expect(compilerOptions.esModuleInterop).toBe(true);
9090
});
9191
});
92+
93+
test.failing("Fails on compiler error", async () => {
94+
const tsconfig = resolve(__dirname, "./tsconfig.json");
95+
96+
await build({
97+
plugins: [dtsPlugin({ tsconfig })],
98+
entryPoints: ["./tests/inputs/index.errors.ts"],
99+
outdir: distDir,
100+
tsconfig,
101+
});
102+
});

tests/inputs/index.errors.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function someFunction(a: string, b: number): string {
2+
return a + b;
3+
}
4+
5+
export type SomeType = "someValue" | "anotherValue";
6+
7+
export const someVar: SomeUndefinedType = "someValue";

0 commit comments

Comments
 (0)