Skip to content

Instantly share code, notes, and snippets.

@mscharley
Created November 11, 2017 04:20
Show Gist options
  • Save mscharley/e0c33a9cad61b02058a4d42a65317fd9 to your computer and use it in GitHub Desktop.
Save mscharley/e0c33a9cad61b02058a4d42a65317fd9 to your computer and use it in GitHub Desktop.
Compile a string in TypeScript using imports and type-checking.
import * as ts from "typescript";
// tslint:disable
export const transpileModule = (input: string, transpileOptions: ts.TranspileOptions): ts.TranspileOutput => {
let diagnostics: ts.Diagnostic[] = [];
const options: ts.CompilerOptions = transpileOptions.compilerOptions || ts.getDefaultCompilerOptions();
options.isolatedModules = true;
/* This function does not write anything to disk so there is no need to verify that
* there are no conflicts between input and output paths.
*/
options.suppressOutputPathCheck = true;
// Filename can be non-ts file.
options.allowNonTsExtensions = true;
// Clear out other settings that would not be used in transpiling this module
options.noEmit = undefined;
options.noEmitOnError = undefined;
// options.paths = undefined;
// options.rootDirs = undefined;
options.declaration = undefined;
options.declarationDir = undefined;
options.out = undefined;
options.outFile = undefined;
// If jsx is specified then treat file as .tsx.
const inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts");
const sourceFile = ts.createSourceFile(inputFileName, input, options.target || ts.ScriptTarget.ES2015);
if (transpileOptions.moduleName) {
sourceFile.moduleName = transpileOptions.moduleName;
}
// Output
let outputText: string = "";
let sourceMapText: string = "";
// Create a compilerHost object to allow the compiler to read and write files
const compilerHost: ts.CompilerHost = ts.createCompilerHost(options);
const oldGetFile = compilerHost.getSourceFile;
compilerHost.getSourceFile = (fileName, version, onError, create) => {
console.log(`Getting ${fileName}`);
if (fileName === inputFileName) {
return sourceFile;
}
else {
return oldGetFile(fileName, version, onError, create);
}
};
compilerHost.writeFile = (name, text) => {
console.log(`Writing file: ${name}:\n${text}`);
// if (fileExtensionIs(name, ".map")) {
// Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name);
// sourceMapText = text;
// }
// else {
// Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name);
// outputText = text;
// }
};
const program = ts.createProgram([inputFileName], options, compilerHost);
if (transpileOptions.reportDiagnostics) {
diagnostics = [
...program.getGlobalDiagnostics(),
...program.getSemanticDiagnostics(),
...program.getSyntacticDiagnostics(sourceFile),
...program.getOptionsDiagnostics(),
];
}
// Emit
program.emit(undefined, undefined, undefined, undefined, transpileOptions.transformers);
if (outputText === undefined) {
throw new Error("Output generation failed");
}
return { outputText, diagnostics, sourceMapText };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment