-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
114 lines (95 loc) · 2.58 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
const path = require("path");
const os = require("os");
const pty = require("node-pty");
class TscError extends Error {
constructor(message) {
super(message);
this.name = "TscError";
this.stack = "";
}
}
const removeNewLinesAtEnd = (str) => str.replace(/(\r\n|\n|\r)+$/g, "");
const PLUGIN_NAME = "tsc-plugin";
class TscWebpackPlugin {
constructor(options = {}) {
this.options = options;
this.initialized = false;
}
async apply(compiler) {
const isWatch = await new Promise((resolve) => {
compiler.hooks.run.tap(PLUGIN_NAME, () => {
if (!this.initialized) {
this.initialized = true;
resolve(false);
}
});
compiler.hooks.watchRun.tap(PLUGIN_NAME, () => {
if (!this.initialized) {
this.initialized = true;
resolve(true);
}
});
});
const file = path.resolve(
compiler.context,
`./node_modules/.bin/tsc${os.platform() === "win32" ? ".exe" : ""}`
);
const options = {
...this.options,
...(isWatch ? { watch: "", preserveWatchOutput: "" } : {}),
};
const args = [
...new Set(
Object.keys(options)
.reduce((acc, key) => [...acc, `--${key}`, String(options[key])], [])
.filter(Boolean)
),
];
const ptyProcess = pty.spawn(file, args, {
name: "xterm-color",
});
process.once("exit", () => {
ptyProcess.emit("exit");
});
const logger = compiler.getInfrastructureLogger(PLUGIN_NAME);
let messages = [];
ptyProcess.onData((data) => {
if (isWatch) {
logger.info(removeNewLinesAtEnd(data));
} else {
messages.push(data);
}
});
if (isWatch) {
ptyProcess.onExit((e) => {
process.exit(e.exitCode);
});
} else {
logger.info("Starting typechecking...");
compiler.hooks.afterEmit.tapPromise(PLUGIN_NAME, async (compilation) => {
await new Promise((resolve) => {
ptyProcess.onExit(() => {
resolve();
});
});
if (messages.length > 0) {
messages
.map((m) =>
removeNewLinesAtEnd(
m
.split("\r\n")
.map((s) => s.replace(/^Found \d+ errors?\b.$/, ""))
.join("\r\n")
)
)
.filter(Boolean)
.map((m) => compilation.errors.push(new TscError(m)));
messages = [];
} else {
logger.info("Found 0 errors.");
}
});
}
}
}
module.exports = TscWebpackPlugin;