mono-runner
Version:
A script runner for mono repos that just works. Use Mono to run separate compilers and dev servers for your packages at once, build only dependent packages or format everything at once.
79 lines (67 loc) • 2.76 kB
text/typescript
import ts from "typescript";
const formatHost: ts.FormatDiagnosticsHost = {
getCanonicalFileName: path => path,
getCurrentDirectory: ts.sys.getCurrentDirectory,
getNewLine: () => ts.sys.newLine
};
export function watchMain() {
const configPath = ts.findConfigFile(
/*searchPath*/ "./",
ts.sys.fileExists,
"tsconfig.json"
);
if (!configPath) {
throw new Error("Could not find a valid 'tsconfig.json'.");
}
// TypeScript can use several different program creation "strategies":
// * ts.createEmitAndSemanticDiagnosticsBuilderProgram,
// * ts.createSemanticDiagnosticsBuilderProgram
// * ts.createAbstractBuilder
// The first two produce "builder programs". These use an incremental strategy
// to only re-check and emit files whose contents may have changed, or whose
// dependencies may have changes which may impact change the result of prior
// type-check and emit.
// The last uses an ordinary program which does a full type check after every
// change.
// Between `createEmitAndSemanticDiagnosticsBuilderProgram` and
// `createSemanticDiagnosticsBuilderProgram`, the only difference is emit.
// For pure type-checking scenarios, or when another tool/process handles emit,
// using `createSemanticDiagnosticsBuilderProgram` may be more desirable.
const createProgram = ts.createSemanticDiagnosticsBuilderProgram;
// Note that there is another overload for `createWatchCompilerHost` that takes
// a set of root files.
const host = ts.createWatchCompilerHost(
configPath,
{preserveSymlinks: true},
ts.sys,
createProgram,
reportDiagnostic,
reportWatchStatusChanged
);
// You can technically override any given hook on the host, though you probably
// don't need to.
// Note that we're assuming `origCreateProgram` and `origPostProgramCreate`
// doesn't use `this` at all.
const origPostProgramCreate = host.afterProgramCreate;
let initial = true;
host.afterProgramCreate = program => {
if(initial){
(process as any).send?.({ event: 'READY' });
initial = false;
}
origPostProgramCreate!(program);
};
// `createWatchProgram` creates an initial program, watches files, and updates
// the program over time.
ts.createWatchProgram(host);
}
function reportDiagnostic(diagnostic: ts.Diagnostic) {
console.error("Error", diagnostic.code, ":", ts.flattenDiagnosticMessageText( diagnostic.messageText, formatHost.getNewLine()));
}
/**
* Prints a diagnostic every time the watch status changes.
* This is mainly for messages like "Starting compilation" or "Compilation completed".
*/
function reportWatchStatusChanged(diagnostic: ts.Diagnostic) {
console.info(ts.formatDiagnostic(diagnostic, formatHost));
}