in packages/concatjs/internal/tsc_wrapped/tsc_wrapped.ts [514:603]
export function emitWithTsickle(
program: ts.Program, compilerHost: CompilerHost,
compilationTargets: ts.SourceFile[], options: ts.CompilerOptions,
bazelOpts: BazelOptions,
transforms: ts.CustomTransformers): ts.Diagnostic[] {
const emitResults: tsickle.EmitResult[] = [];
const diagnostics: ts.Diagnostic[] = [];
// The 'tsickle' import above is only used in type positions, so it won't
// result in a runtime dependency on tsickle.
// If the user requests the tsickle emit, then we dynamically require it
// here for use at runtime.
let optTsickle: typeof tsickle;
try {
// tslint:disable-next-line:no-require-imports
optTsickle = require('tsickle');
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') {
throw e;
}
throw new Error(
'When setting bazelOpts { tsickle: true }, ' +
'you must also add a devDependency on the tsickle npm package');
}
perfTrace.wrap('emit', () => {
for (const sf of compilationTargets) {
perfTrace.wrap(`emit ${sf.fileName}`, () => {
emitResults.push(optTsickle.emitWithTsickle(
program, compilerHost, compilerHost, options, sf,
/*writeFile*/ undefined,
/*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, {
beforeTs: transforms.before,
afterTs: transforms.after,
afterDeclarations: transforms.afterDeclarations,
}));
});
}
});
const emitResult = optTsickle.mergeEmitResults(emitResults);
diagnostics.push(...emitResult.diagnostics);
// If tsickle reported diagnostics, don't produce externs or manifest outputs.
if (diagnostics.length > 0) {
return diagnostics;
}
let externs = '/** @externs */\n' +
'// generating externs was disabled using generate_externs=False\n';
if (bazelOpts.tsickleGenerateExterns) {
externs =
optTsickle.getGeneratedExterns(emitResult.externs, options.rootDir!);
}
if (!options.noEmit && bazelOpts.tsickleExternsPath) {
// Note: when tsickleExternsPath is provided, we always write a file as a
// marker that compilation succeeded, even if it's empty (just containing an
// @externs).
fs.writeFileSync(bazelOpts.tsickleExternsPath, externs);
// When generating externs, generate an externs file for each of the input
// .d.ts files.
if (bazelOpts.tsickleGenerateExterns &&
compilerHost.provideExternalModuleDtsNamespace) {
for (const extern of compilationTargets) {
if (!extern.isDeclarationFile) continue;
const outputBaseDir = options.outDir!;
const relativeOutputPath =
compilerHost.relativeOutputPath(extern.fileName);
mkdirp(outputBaseDir, path.dirname(relativeOutputPath));
const outputPath = path.join(outputBaseDir, relativeOutputPath);
const moduleName = compilerHost.pathToModuleName('', extern.fileName);
fs.writeFileSync(
outputPath,
`goog.module('${moduleName}');\n` +
`// Export an empty object of unknown type to allow imports.\n` +
`// TODO: use typeof once available\n` +
`exports = /** @type {?} */ ({});\n`);
}
}
}
if (!options.noEmit && bazelOpts.manifest) {
perfTrace.wrap('manifest', () => {
const manifest =
constructManifest(emitResult.modulesManifest, compilerHost);
fs.writeFileSync(bazelOpts.manifest, manifest);
});
}
return diagnostics;
}