instances.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.getEmitOutput = exports.getEmitFromWatchHost = exports.getInputFileNameFromOutput = exports.getOutputFileNames = exports.forEachResolvedProjectReference = exports.buildSolutionReferences = exports.reportTranspileErrors = exports.getCustomTransformers = exports.initializeInstance = exports.getTypeScriptInstance = void 0;
  4. const chalk = require("chalk");
  5. const fs = require("fs");
  6. const path = require("path");
  7. const webpack = require("webpack");
  8. const after_compile_1 = require("./after-compile");
  9. const compilerSetup_1 = require("./compilerSetup");
  10. const config_1 = require("./config");
  11. const constants_1 = require("./constants");
  12. const instance_cache_1 = require("./instance-cache");
  13. const logger = require("./logger");
  14. const servicesHost_1 = require("./servicesHost");
  15. const utils_1 = require("./utils");
  16. const watch_run_1 = require("./watch-run");
  17. const instancesBySolutionBuilderConfigs = new Map();
  18. /**
  19. * The loader is executed once for each file seen by webpack. However, we need to keep
  20. * a persistent instance of TypeScript that contains all of the files in the program
  21. * along with definition files and options. This function either creates an instance
  22. * or returns the existing one. Multiple instances are possible by using the
  23. * `instance` property.
  24. */
  25. function getTypeScriptInstance(loaderOptions, loader) {
  26. const existing = (0, instance_cache_1.getTSInstanceFromCache)(loader._compiler, loaderOptions.instance);
  27. if (existing) {
  28. if (!existing.initialSetupPending) {
  29. (0, utils_1.ensureProgram)(existing);
  30. }
  31. return { instance: existing };
  32. }
  33. const level = loaderOptions.colors && chalk.supportsColor ? chalk.supportsColor.level : 0;
  34. const colors = new chalk.Instance({ level });
  35. const log = logger.makeLogger(loaderOptions, colors);
  36. const compiler = (0, compilerSetup_1.getCompiler)(loaderOptions, log);
  37. if (compiler.errorMessage !== undefined) {
  38. return {
  39. error: (0, utils_1.makeError)(loaderOptions, colors.red(compiler.errorMessage), ''),
  40. };
  41. }
  42. return successfulTypeScriptInstance(loaderOptions, loader, log, colors, compiler.compiler, compiler.compilerCompatible, compiler.compilerDetailsLogMessage);
  43. }
  44. exports.getTypeScriptInstance = getTypeScriptInstance;
  45. function createFilePathKeyMapper(compiler, loaderOptions) {
  46. // Cache file path key - a map lookup is much faster than filesystem/regex operations & the result will never change
  47. const filePathMapperCache = new Map();
  48. // FileName lowercasing copied from typescript
  49. const fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_\. ]+/g;
  50. return (0, utils_1.useCaseSensitiveFileNames)(compiler, loaderOptions)
  51. ? pathResolve
  52. : toFileNameLowerCase;
  53. function pathResolve(filePath) {
  54. let cachedPath = filePathMapperCache.get(filePath);
  55. if (!cachedPath) {
  56. cachedPath = path.resolve(filePath);
  57. filePathMapperCache.set(filePath, cachedPath);
  58. }
  59. return cachedPath;
  60. }
  61. function toFileNameLowerCase(filePath) {
  62. let cachedPath = filePathMapperCache.get(filePath);
  63. if (!cachedPath) {
  64. const filePathKey = pathResolve(filePath);
  65. cachedPath = fileNameLowerCaseRegExp.test(filePathKey)
  66. ? filePathKey.replace(fileNameLowerCaseRegExp, ch => ch.toLowerCase())
  67. : filePathKey;
  68. filePathMapperCache.set(filePath, cachedPath);
  69. }
  70. return cachedPath;
  71. }
  72. }
  73. function successfulTypeScriptInstance(loaderOptions, loader, log, colors, compiler, compilerCompatible, compilerDetailsLogMessage) {
  74. const configFileAndPath = (0, config_1.getConfigFile)(compiler, colors, loader, loaderOptions, compilerCompatible, log, compilerDetailsLogMessage);
  75. if (configFileAndPath.configFileError !== undefined) {
  76. const { message, file } = configFileAndPath.configFileError;
  77. return {
  78. error: (0, utils_1.makeError)(loaderOptions, colors.red('error while reading tsconfig.json:' + constants_1.EOL + message), file),
  79. };
  80. }
  81. const { configFilePath, configFile } = configFileAndPath;
  82. if (configFilePath) {
  83. loader.addBuildDependency(configFilePath);
  84. }
  85. const filePathKeyMapper = createFilePathKeyMapper(compiler, loaderOptions);
  86. if (configFilePath && loaderOptions.projectReferences) {
  87. const configFileKey = filePathKeyMapper(configFilePath);
  88. const existing = getExistingSolutionBuilderHost(configFileKey);
  89. if (existing) {
  90. // Reuse the instance if config file for project references is shared.
  91. (0, instance_cache_1.setTSInstanceInCache)(loader._compiler, loaderOptions.instance, existing);
  92. return { instance: existing };
  93. }
  94. }
  95. const module = loader._module;
  96. const basePath = loaderOptions.context || path.dirname(configFilePath || '');
  97. const configParseResult = (0, config_1.getConfigParseResult)(compiler, configFile, basePath, configFilePath, loaderOptions);
  98. if (configParseResult.errors.length > 0 && !loaderOptions.happyPackMode) {
  99. const errors = (0, utils_1.formatErrors)(configParseResult.errors, loaderOptions, colors, compiler, { file: configFilePath }, loader.context);
  100. errors.forEach(error => module.addError(error));
  101. return {
  102. error: (0, utils_1.makeError)(loaderOptions, colors.red('error while parsing tsconfig.json'), configFilePath || ''),
  103. };
  104. }
  105. const compilerOptions = (0, compilerSetup_1.getCompilerOptions)(configParseResult, compiler);
  106. const rootFileNames = new Set();
  107. const files = new Map();
  108. const otherFiles = new Map();
  109. const appendTsTsxSuffixesIfRequired = loaderOptions.appendTsSuffixTo.length > 0 ||
  110. loaderOptions.appendTsxSuffixTo.length > 0
  111. ? (filePath) => (0, utils_1.appendSuffixesIfMatch)({
  112. '.ts': loaderOptions.appendTsSuffixTo,
  113. '.tsx': loaderOptions.appendTsxSuffixTo,
  114. }, filePath)
  115. : (filePath) => filePath;
  116. if (loaderOptions.transpileOnly) {
  117. // quick return for transpiling
  118. // we do need to check for any issues with TS options though
  119. const transpileInstance = {
  120. compiler,
  121. compilerOptions,
  122. appendTsTsxSuffixesIfRequired,
  123. loaderOptions,
  124. rootFileNames,
  125. files,
  126. otherFiles,
  127. version: 0,
  128. program: undefined,
  129. dependencyGraph: new Map(),
  130. transformers: {},
  131. colors,
  132. initialSetupPending: true,
  133. reportTranspileErrors: true,
  134. configFilePath,
  135. configParseResult,
  136. log,
  137. filePathKeyMapper,
  138. };
  139. (0, instance_cache_1.setTSInstanceInCache)(loader._compiler, loaderOptions.instance, transpileInstance);
  140. return { instance: transpileInstance };
  141. }
  142. // Load initial files (core lib files, any files specified in tsconfig.json)
  143. let normalizedFilePath;
  144. try {
  145. const filesToLoad = loaderOptions.onlyCompileBundledFiles
  146. ? configParseResult.fileNames.filter(fileName => constants_1.dtsDtsxOrDtsDtsxMapRegex.test(fileName))
  147. : configParseResult.fileNames;
  148. filesToLoad.forEach(filePath => {
  149. normalizedFilePath = path.normalize(filePath);
  150. files.set(filePathKeyMapper(normalizedFilePath), {
  151. fileName: normalizedFilePath,
  152. text: fs.readFileSync(normalizedFilePath, 'utf-8'),
  153. version: 0,
  154. });
  155. rootFileNames.add(normalizedFilePath);
  156. });
  157. }
  158. catch (exc) {
  159. return {
  160. error: (0, utils_1.makeError)(loaderOptions, colors.red(`A file specified in tsconfig.json could not be found: ${normalizedFilePath}`), normalizedFilePath),
  161. };
  162. }
  163. const instance = {
  164. compiler,
  165. compilerOptions,
  166. appendTsTsxSuffixesIfRequired,
  167. loaderOptions,
  168. rootFileNames,
  169. files,
  170. otherFiles,
  171. languageService: null,
  172. version: 0,
  173. transformers: {},
  174. dependencyGraph: new Map(),
  175. colors,
  176. initialSetupPending: true,
  177. configFilePath,
  178. configParseResult,
  179. log,
  180. filePathKeyMapper,
  181. };
  182. (0, instance_cache_1.setTSInstanceInCache)(loader._compiler, loaderOptions.instance, instance);
  183. return { instance };
  184. }
  185. function getExistingSolutionBuilderHost(key) {
  186. const existing = instancesBySolutionBuilderConfigs.get(key);
  187. if (existing)
  188. return existing;
  189. for (const instance of instancesBySolutionBuilderConfigs.values()) {
  190. if (instance.solutionBuilderHost.configFileInfo.has(key)) {
  191. return instance;
  192. }
  193. }
  194. return undefined;
  195. }
  196. function addAssetHooks(loader, instance) {
  197. // makeAfterCompile is a closure. It returns a function which closes over the variable checkAllFilesForErrors
  198. // We need to get the function once and then reuse it, otherwise it will be recreated each time
  199. // and all files will always be checked.
  200. const cachedMakeAfterCompile = (0, after_compile_1.makeAfterCompile)(instance, instance.configFilePath);
  201. const makeAssetsCallback = (compilation) => {
  202. compilation.hooks.processAssets.tap({
  203. name: 'ts-loader',
  204. stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
  205. }, () => {
  206. cachedMakeAfterCompile(compilation, () => {
  207. return null;
  208. });
  209. });
  210. };
  211. // We need to add the hook above for each run.
  212. // For the first run, we just need to add the hook to loader._compilation
  213. makeAssetsCallback(loader._compilation);
  214. // For future calls in watch mode we need to watch for a new compilation and add the hook
  215. loader._compiler.hooks.compilation.tap('ts-loader', makeAssetsCallback);
  216. }
  217. function initializeInstance(loader, instance) {
  218. if (!instance.initialSetupPending) {
  219. return;
  220. }
  221. instance.initialSetupPending = false;
  222. if (instance.loaderOptions.transpileOnly) {
  223. const program = (instance.program =
  224. instance.configParseResult.projectReferences !== undefined
  225. ? instance.compiler.createProgram({
  226. rootNames: instance.configParseResult.fileNames,
  227. options: instance.configParseResult.options,
  228. projectReferences: instance.configParseResult.projectReferences,
  229. })
  230. : instance.compiler.createProgram([], instance.compilerOptions));
  231. const getProgram = () => program;
  232. instance.transformers = getCustomTransformers(instance.loaderOptions, program, getProgram);
  233. // Setup watch run for solution building
  234. if (instance.solutionBuilderHost) {
  235. addAssetHooks(loader, instance);
  236. loader._compiler.hooks.watchRun.tapAsync('ts-loader', (0, watch_run_1.makeWatchRun)(instance, loader));
  237. }
  238. }
  239. else {
  240. if (!loader._compiler.hooks) {
  241. throw new Error("You may be using an old version of webpack; please check you're using at least version 4");
  242. }
  243. if (instance.loaderOptions.experimentalWatchApi) {
  244. instance.log.logInfo('Using watch api');
  245. // If there is api available for watch, use it instead of language service
  246. instance.watchHost = (0, servicesHost_1.makeWatchHost)(getScriptRegexp(instance), loader, instance, instance.configParseResult.projectReferences);
  247. instance.watchOfFilesAndCompilerOptions =
  248. instance.compiler.createWatchProgram(instance.watchHost);
  249. instance.builderProgram =
  250. instance.watchOfFilesAndCompilerOptions.getProgram();
  251. const getProgram = () => { var _a; return (_a = instance.builderProgram) === null || _a === void 0 ? void 0 : _a.getProgram(); };
  252. instance.program = getProgram();
  253. instance.transformers = getCustomTransformers(instance.loaderOptions, instance.program, getProgram);
  254. }
  255. else {
  256. instance.servicesHost = (0, servicesHost_1.makeServicesHost)(getScriptRegexp(instance), loader, instance, instance.configParseResult.projectReferences);
  257. instance.languageService = instance.compiler.createLanguageService(instance.servicesHost, instance.compiler.createDocumentRegistry());
  258. const getProgram = () => instance.languageService.getProgram();
  259. instance.transformers = getCustomTransformers(instance.loaderOptions, getProgram(), getProgram);
  260. }
  261. addAssetHooks(loader, instance);
  262. loader._compiler.hooks.watchRun.tapAsync('ts-loader', (0, watch_run_1.makeWatchRun)(instance, loader));
  263. }
  264. }
  265. exports.initializeInstance = initializeInstance;
  266. function getCustomTransformers(loaderOptions, program, getProgram) {
  267. // same strategy as https://github.com/s-panferov/awesome-typescript-loader/pull/531/files
  268. let { getCustomTransformers: customerTransformers } = loaderOptions;
  269. let getCustomTransformers = Function.prototype;
  270. if (typeof customerTransformers === 'function') {
  271. getCustomTransformers = customerTransformers;
  272. }
  273. else if (typeof customerTransformers === 'string') {
  274. try {
  275. customerTransformers = require(customerTransformers);
  276. }
  277. catch (err) {
  278. throw new Error(`Failed to load customTransformers from "${loaderOptions.getCustomTransformers}": ${err instanceof Error ? err.message : 'unknown error'}`);
  279. }
  280. if (typeof customerTransformers !== 'function') {
  281. throw new Error(`Custom transformers in "${loaderOptions.getCustomTransformers}" should export a function, got ${typeof customerTransformers}`);
  282. }
  283. getCustomTransformers = customerTransformers;
  284. }
  285. return getCustomTransformers(program, getProgram);
  286. }
  287. exports.getCustomTransformers = getCustomTransformers;
  288. function getScriptRegexp(instance) {
  289. // If resolveJsonModules is set, we should accept json files
  290. if (instance.configParseResult.options.resolveJsonModule) {
  291. // if allowJs is set then we should accept js(x) files
  292. return instance.configParseResult.options.allowJs === true
  293. ? /\.([cm]?[tj]s|[tj]sx|json)$/i
  294. : /\.([cm]?ts|tsx|json)$/i;
  295. }
  296. // if allowJs is set then we should accept js(x) files
  297. return instance.configParseResult.options.allowJs === true
  298. ? /\.([cm]?[tj]s|[tj]sx)$/i
  299. : /\.([cm]?ts|tsx)$/i;
  300. }
  301. function reportTranspileErrors(instance, loader) {
  302. if (!instance.reportTranspileErrors) {
  303. return;
  304. }
  305. const module = loader._module;
  306. instance.reportTranspileErrors = false;
  307. // happypack does not have _module.errors - see https://github.com/TypeStrong/ts-loader/issues/336
  308. if (!instance.loaderOptions.happyPackMode) {
  309. const solutionErrors = (0, servicesHost_1.getSolutionErrors)(instance, loader.context);
  310. const diagnostics = instance.program.getOptionsDiagnostics();
  311. const errors = (0, utils_1.formatErrors)(diagnostics, instance.loaderOptions, instance.colors, instance.compiler, { file: instance.configFilePath || 'tsconfig.json' }, loader.context);
  312. [...solutionErrors, ...errors].forEach(error => module.addError(error));
  313. }
  314. }
  315. exports.reportTranspileErrors = reportTranspileErrors;
  316. function buildSolutionReferences(instance, loader) {
  317. if (!(0, utils_1.supportsSolutionBuild)(instance)) {
  318. return;
  319. }
  320. if (!instance.solutionBuilderHost) {
  321. // Use solution builder
  322. instance.log.logInfo('Using SolutionBuilder api');
  323. const scriptRegex = getScriptRegexp(instance);
  324. instance.solutionBuilderHost = (0, servicesHost_1.makeSolutionBuilderHost)(scriptRegex, loader, instance);
  325. const solutionBuilder = instance.compiler.createSolutionBuilderWithWatch(instance.solutionBuilderHost, instance.configParseResult.projectReferences.map(ref => ref.path), { verbose: true });
  326. solutionBuilder.build();
  327. instance.solutionBuilderHost.ensureAllReferenceTimestamps();
  328. instancesBySolutionBuilderConfigs.set(instance.filePathKeyMapper(instance.configFilePath), instance);
  329. }
  330. else {
  331. instance.solutionBuilderHost.buildReferences();
  332. }
  333. }
  334. exports.buildSolutionReferences = buildSolutionReferences;
  335. function forEachResolvedProjectReference(resolvedProjectReferences, cb) {
  336. let seenResolvedRefs;
  337. return worker(resolvedProjectReferences);
  338. function worker(resolvedRefs) {
  339. if (resolvedRefs) {
  340. for (const resolvedRef of resolvedRefs) {
  341. if (!resolvedRef) {
  342. continue;
  343. }
  344. if (seenResolvedRefs &&
  345. seenResolvedRefs.some(seenRef => seenRef === resolvedRef)) {
  346. // ignore recursives
  347. continue;
  348. }
  349. (seenResolvedRefs || (seenResolvedRefs = [])).push(resolvedRef);
  350. const result = cb(resolvedRef) || worker(resolvedRef.references);
  351. if (result) {
  352. return result;
  353. }
  354. }
  355. }
  356. return undefined;
  357. }
  358. }
  359. exports.forEachResolvedProjectReference = forEachResolvedProjectReference;
  360. // This code is here as a temporary holder
  361. function fileExtensionIs(fileName, ext) {
  362. return fileName.endsWith(ext);
  363. }
  364. function rootDirOfOptions(instance, configFile) {
  365. return (configFile.options.rootDir ||
  366. instance.compiler.getDirectoryPath(configFile.options.configFilePath));
  367. }
  368. function getOutputPathWithoutChangingExt(instance, inputFileName, configFile, ignoreCase, outputDir) {
  369. return outputDir
  370. ? instance.compiler.resolvePath(outputDir, instance.compiler.getRelativePathFromDirectory(rootDirOfOptions(instance, configFile), inputFileName, ignoreCase))
  371. : inputFileName;
  372. }
  373. function getOutputJSFileName(instance, inputFileName, configFile, ignoreCase) {
  374. if (configFile.options.emitDeclarationOnly) {
  375. return undefined;
  376. }
  377. const isJsonFile = fileExtensionIs(inputFileName, '.json');
  378. const outputFileName = instance.compiler.changeExtension(getOutputPathWithoutChangingExt(instance, inputFileName, configFile, ignoreCase, configFile.options.outDir), isJsonFile
  379. ? '.json'
  380. : fileExtensionIs(inputFileName, '.tsx') &&
  381. configFile.options.jsx === instance.compiler.JsxEmit.Preserve
  382. ? '.jsx'
  383. : '.js');
  384. return !isJsonFile ||
  385. instance.compiler.comparePaths(inputFileName, outputFileName, configFile.options.configFilePath, ignoreCase) !== instance.compiler.Comparison.EqualTo
  386. ? outputFileName
  387. : undefined;
  388. }
  389. function getOutputFileNames(instance, configFile, inputFileName) {
  390. const ignoreCase = !(0, utils_1.useCaseSensitiveFileNames)(instance.compiler, instance.loaderOptions);
  391. if (instance.compiler.getOutputFileNames) {
  392. return instance.compiler.getOutputFileNames(configFile, inputFileName, ignoreCase);
  393. }
  394. const outputs = [];
  395. const addOutput = (fileName) => fileName && outputs.push(fileName);
  396. const js = getOutputJSFileName(instance, inputFileName, configFile, ignoreCase);
  397. addOutput(js);
  398. if (!fileExtensionIs(inputFileName, '.json')) {
  399. if (js && configFile.options.sourceMap) {
  400. addOutput(`${js}.map`);
  401. }
  402. if ((configFile.options.declaration || configFile.options.composite) &&
  403. instance.compiler.hasTSFileExtension(inputFileName)) {
  404. const dts = instance.compiler.getOutputDeclarationFileName(inputFileName, configFile, ignoreCase);
  405. addOutput(dts);
  406. if (configFile.options.declarationMap) {
  407. addOutput(`${dts}.map`);
  408. }
  409. }
  410. }
  411. return outputs;
  412. }
  413. exports.getOutputFileNames = getOutputFileNames;
  414. function getInputFileNameFromOutput(instance, filePath) {
  415. if (filePath.match(constants_1.tsTsxRegex) && !constants_1.declarationRegex.test(filePath)) {
  416. return undefined;
  417. }
  418. if (instance.solutionBuilderHost) {
  419. return instance.solutionBuilderHost.getInputFileNameFromOutput(filePath);
  420. }
  421. const program = (0, utils_1.ensureProgram)(instance);
  422. return (program &&
  423. program.getResolvedProjectReferences &&
  424. forEachResolvedProjectReference(program.getResolvedProjectReferences(), ({ commandLine }) => {
  425. const { options, fileNames } = commandLine;
  426. if (!options.outFile && !options.out) {
  427. const input = fileNames.find(file => getOutputFileNames(instance, commandLine, file).find(name => path.resolve(name) === filePath));
  428. return input && path.resolve(input);
  429. }
  430. return undefined;
  431. }));
  432. }
  433. exports.getInputFileNameFromOutput = getInputFileNameFromOutput;
  434. function getEmitFromWatchHost(instance, filePath) {
  435. const program = (0, utils_1.ensureProgram)(instance);
  436. const builderProgram = instance.builderProgram;
  437. if (builderProgram && program) {
  438. if (filePath) {
  439. const existing = instance.watchHost.outputFiles.get(instance.filePathKeyMapper(filePath));
  440. if (existing) {
  441. return existing;
  442. }
  443. }
  444. const outputFiles = [];
  445. const writeFile = (fileName, text, writeByteOrderMark) => {
  446. if (fileName.endsWith('.tsbuildinfo')) {
  447. instance.watchHost.tsbuildinfo = {
  448. name: fileName,
  449. writeByteOrderMark,
  450. text,
  451. };
  452. }
  453. else {
  454. outputFiles.push({ name: fileName, writeByteOrderMark, text });
  455. }
  456. };
  457. const sourceFile = filePath ? program.getSourceFile(filePath) : undefined;
  458. // Try emit Next file
  459. while (true) {
  460. const result = builderProgram.emitNextAffectedFile(writeFile,
  461. /*cancellationToken*/ undefined,
  462. /*emitOnlyDtsFiles*/ false, instance.transformers);
  463. if (!result) {
  464. break;
  465. }
  466. // Only put the output file in the cache if the source came from webpack and
  467. // was processed by the loaders
  468. if (result.affected === sourceFile) {
  469. instance.watchHost.outputFiles.set(instance.filePathKeyMapper(result.affected.fileName), outputFiles.slice());
  470. return outputFiles;
  471. }
  472. }
  473. }
  474. return undefined;
  475. }
  476. exports.getEmitFromWatchHost = getEmitFromWatchHost;
  477. function getEmitOutput(instance, filePath) {
  478. if (fileExtensionIs(filePath, instance.compiler.Extension.Dts)) {
  479. return [];
  480. }
  481. if ((0, utils_1.isReferencedFile)(instance, filePath)) {
  482. return instance.solutionBuilderHost.getOutputFilesFromReferencedProjectInput(filePath);
  483. }
  484. const program = (0, utils_1.ensureProgram)(instance);
  485. if (program !== undefined) {
  486. const sourceFile = program.getSourceFile(filePath);
  487. const outputFiles = [];
  488. const writeFile = (fileName, text, writeByteOrderMark) => outputFiles.push({ name: fileName, writeByteOrderMark, text });
  489. const outputFilesFromWatch = getEmitFromWatchHost(instance, filePath);
  490. if (outputFilesFromWatch) {
  491. return outputFilesFromWatch;
  492. }
  493. program.emit(sourceFile, writeFile,
  494. /*cancellationToken*/ undefined,
  495. /*emitOnlyDtsFiles*/ false, instance.transformers);
  496. return outputFiles;
  497. }
  498. else {
  499. // Emit Javascript
  500. return instance.languageService.getProgram().getSourceFile(filePath) ===
  501. undefined
  502. ? []
  503. : instance.languageService.getEmitOutput(filePath).outputFiles;
  504. }
  505. }
  506. exports.getEmitOutput = getEmitOutput;
  507. //# sourceMappingURL=instances.js.map