Created
November 11, 2017 04:20
-
-
Save mscharley/e0c33a9cad61b02058a4d42a65317fd9 to your computer and use it in GitHub Desktop.
Compile a string in TypeScript using imports and type-checking.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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