fix(compiler): Refactor compiler implementation with consolidated TsBuild class and improved diagnostics handling
This commit is contained in:
		| @@ -1,5 +1,12 @@ | ||||
| # Changelog | ||||
|  | ||||
| ## 2025-03-20 - 2.3.1 - fix(compiler) | ||||
| Refactor compiler implementation with consolidated TsBuild class and improved diagnostics handling | ||||
|  | ||||
| - Removed legacy tsbuild.classes.compiler.ts and introduced tsbuild.classes.tsbuild.ts | ||||
| - Unified compiler options merging, reading tsconfig.json, and diagnostics reporting within the TsBuild class | ||||
| - Updated exports to reference the new compiler class implementation for backward compatibility | ||||
|  | ||||
| ## 2025-03-20 - 2.3.0 - feat(cli) | ||||
| Add emitcheck command to validate TS file emission without generating output | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,6 @@ | ||||
|  */ | ||||
| export const commitinfo = { | ||||
|   name: '@git.zone/tsbuild', | ||||
|   version: '2.3.0', | ||||
|   version: '2.3.1', | ||||
|   description: 'A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.' | ||||
| } | ||||
|   | ||||
| @@ -1,215 +0,0 @@ | ||||
| // import all the stuff we need | ||||
| import * as plugins from './plugins.js'; | ||||
| import * as paths from './paths.js'; | ||||
| import type { CompilerOptions, ScriptTarget, ModuleKind } from './tsbuild.exports.js'; | ||||
|  | ||||
| /** | ||||
|  * the default typescript compilerOptions | ||||
|  */ | ||||
| export const compilerOptionsDefault: CompilerOptions = { | ||||
|   declaration: true, | ||||
|   emitDecoratorMetadata: true, | ||||
|   experimentalDecorators: true, | ||||
|   inlineSourceMap: true, | ||||
|   noEmitOnError: true, | ||||
|   outDir: 'dist_ts/', | ||||
|   module: plugins.typescript.ModuleKind.NodeNext, | ||||
|   target: plugins.typescript.ScriptTarget.ESNext, | ||||
|   moduleResolution: plugins.typescript.ModuleResolutionKind.NodeNext, | ||||
|   lib: ['lib.dom.d.ts', 'lib.es2022.d.ts'], | ||||
|   noImplicitAny: true, | ||||
|   esModuleInterop: true, | ||||
|   useDefineForClassFields: false, | ||||
|   verbatimModuleSyntax: true, | ||||
|   baseUrl: './', | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * merges compilerOptions with the default compiler options | ||||
|  */ | ||||
| export const mergeCompilerOptions = ( | ||||
|   customTsOptions: CompilerOptions, | ||||
|   argvArg?: any | ||||
| ): CompilerOptions => { | ||||
|   // create merged options | ||||
|   const mergedOptions: CompilerOptions = { | ||||
|     ...compilerOptionsDefault, | ||||
|     ...customTsOptions, | ||||
|     ...(argvArg && argvArg.skiplibcheck | ||||
|       ? { | ||||
|           skipLibCheck: true, | ||||
|         } | ||||
|       : {}), | ||||
|     ...(argvArg && argvArg.allowimplicitany | ||||
|       ? { | ||||
|           noImplicitAny: false, | ||||
|         } | ||||
|       : {}), | ||||
|     ...(argvArg && argvArg.commonjs | ||||
|       ? { | ||||
|           module: plugins.typescript.ModuleKind.CommonJS, | ||||
|           moduleResolution: plugins.typescript.ModuleResolutionKind.NodeJs, | ||||
|         } | ||||
|       : {}), | ||||
|     ...(() => { | ||||
|       const returnObject: CompilerOptions = {}; | ||||
|       console.log(`looking at tsconfig.json at ${paths.cwd}`); | ||||
|       const tsconfig = plugins.smartfile.fs.toObjectSync(plugins.path.join(paths.cwd, 'tsconfig.json')); | ||||
|       if (tsconfig && tsconfig.compilerOptions && tsconfig.compilerOptions.baseUrl) { | ||||
|         console.log('baseUrl found in tsconfig.json'); | ||||
|         returnObject.baseUrl = tsconfig.compilerOptions.baseUrl; | ||||
|       } | ||||
|       if (tsconfig && tsconfig.compilerOptions && tsconfig.compilerOptions.paths) { | ||||
|         console.log('paths found in tsconfig.json'); | ||||
|         returnObject.paths = tsconfig.compilerOptions.paths; | ||||
|         for (const path of Object.keys(tsconfig.compilerOptions.paths)) { | ||||
|           returnObject.paths[path][0] = returnObject.paths[path][0].replace('./ts_', './dist_ts_'); | ||||
|         } | ||||
|       } | ||||
|       return returnObject; | ||||
|     })(), | ||||
|   }; | ||||
|  | ||||
|   console.log(mergedOptions); | ||||
|  | ||||
|   return mergedOptions; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * the internal main compiler function that compiles the files | ||||
|  */ | ||||
| export const compiler = async ( | ||||
|   fileNames: string[], | ||||
|   options: plugins.typescript.CompilerOptions, | ||||
|   argvArg?: any | ||||
| ): Promise<any[]> => { | ||||
|   if (options.skipLibCheck) { | ||||
|     console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?'); | ||||
|     console.log('You are skipping libcheck... Is that really wanted?'); | ||||
|     console.log('continuing in 5 seconds...'); | ||||
|     console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?'); | ||||
|     await plugins.smartdelay.delayFor(5000); | ||||
|   } | ||||
|   console.log(`Compiling ${fileNames.length} files...`); | ||||
|   const done = plugins.smartpromise.defer<any[]>(); | ||||
|   const program = plugins.typescript.createProgram(fileNames, options); | ||||
|    | ||||
|   // Check for pre-emit diagnostics first | ||||
|   const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program); | ||||
|   let hasErrors = false; | ||||
|    | ||||
|   // Log pre-emit diagnostics if any | ||||
|   if (preEmitDiagnostics.length > 0) { | ||||
|     preEmitDiagnostics.forEach((diagnostic) => { | ||||
|       hasErrors = true; | ||||
|       if (diagnostic.file) { | ||||
|         const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); | ||||
|         const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); | ||||
|         console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); | ||||
|       } else { | ||||
|         console.log( | ||||
|           `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}` | ||||
|         ); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|    | ||||
|   // Only continue to emit phase if no pre-emit errors | ||||
|   if (hasErrors) { | ||||
|     console.error('TypeScript pre-emit checks failed. Please fix the issues above.'); | ||||
|     process.exit(1); | ||||
|   } | ||||
|    | ||||
|   // If no pre-emit errors, proceed with emit | ||||
|   const emitResult = program.emit(); | ||||
|    | ||||
|   // Check for emit diagnostics | ||||
|   if (emitResult.diagnostics.length > 0) { | ||||
|     emitResult.diagnostics.forEach((diagnostic) => { | ||||
|       if (diagnostic.file) { | ||||
|         const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); | ||||
|         const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); | ||||
|         console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); | ||||
|       } else { | ||||
|         console.log( | ||||
|           `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}` | ||||
|         ); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   const exitCode = emitResult.emitSkipped ? 1 : 0; | ||||
|   if (exitCode === 0) { | ||||
|     console.log('TypeScript emit succeeded!'); | ||||
|     done.resolve(emitResult.emittedFiles); | ||||
|   } else { | ||||
|     console.error('TypeScript emit failed. Please investigate!'); | ||||
|     process.exit(exitCode); | ||||
|   } | ||||
|  | ||||
|   return done.promise; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Function to check if a TypeScript file can be emitted without actually emitting it | ||||
|  */ | ||||
| export const emitCheck = async ( | ||||
|   fileNames: string[], | ||||
|   options: plugins.typescript.CompilerOptions = {}, | ||||
|   argvArg?: any | ||||
| ): Promise<boolean> => { | ||||
|   console.log(`Checking if ${fileNames.length} files can be emitted...`); | ||||
|    | ||||
|   // Create a program | ||||
|   const program = plugins.typescript.createProgram(fileNames, { | ||||
|     ...options, | ||||
|     noEmit: true | ||||
|   }); | ||||
|    | ||||
|   // Check for pre-emit diagnostics | ||||
|   const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program); | ||||
|   let hasErrors = false; | ||||
|    | ||||
|   // Log pre-emit diagnostics if any | ||||
|   if (preEmitDiagnostics.length > 0) { | ||||
|     preEmitDiagnostics.forEach((diagnostic) => { | ||||
|       hasErrors = true; | ||||
|       if (diagnostic.file) { | ||||
|         const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); | ||||
|         const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); | ||||
|         console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); | ||||
|       } else { | ||||
|         console.log( | ||||
|           `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}` | ||||
|         ); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|    | ||||
|   // Run the emit phase but with noEmit: true to check for emit errors without producing files | ||||
|   const emitResult = program.emit(undefined, undefined, undefined, true); | ||||
|    | ||||
|   // Check for emit diagnostics | ||||
|   if (emitResult.diagnostics.length > 0) { | ||||
|     emitResult.diagnostics.forEach((diagnostic) => { | ||||
|       hasErrors = true; | ||||
|       if (diagnostic.file) { | ||||
|         const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); | ||||
|         const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); | ||||
|         console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); | ||||
|       } else { | ||||
|         console.log( | ||||
|           `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}` | ||||
|         ); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|    | ||||
|   if (!hasErrors && !emitResult.emitSkipped) { | ||||
|     console.log('TypeScript emit check passed! File can be emitted successfully.'); | ||||
|     return true; | ||||
|   } else { | ||||
|     console.error('TypeScript emit check failed. Please fix the issues above.'); | ||||
|     return false; | ||||
|   } | ||||
| }; | ||||
							
								
								
									
										271
									
								
								ts/tsbuild.classes.tsbuild.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								ts/tsbuild.classes.tsbuild.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,271 @@ | ||||
| // import all the stuff we need | ||||
| import * as plugins from './plugins.js'; | ||||
| import * as paths from './paths.js'; | ||||
| import type { CompilerOptions, ScriptTarget, ModuleKind } from './tsbuild.exports.js'; | ||||
|  | ||||
| /** | ||||
|  * Default compiler options for TypeScript compilation | ||||
|  */ | ||||
| export const compilerOptionsDefault: CompilerOptions = { | ||||
|   declaration: true, | ||||
|   emitDecoratorMetadata: true, | ||||
|   experimentalDecorators: true, | ||||
|   inlineSourceMap: true, | ||||
|   noEmitOnError: true, | ||||
|   outDir: 'dist_ts/', | ||||
|   module: plugins.typescript.ModuleKind.NodeNext, | ||||
|   target: plugins.typescript.ScriptTarget.ESNext, | ||||
|   moduleResolution: plugins.typescript.ModuleResolutionKind.NodeNext, | ||||
|   lib: ['lib.dom.d.ts', 'lib.es2022.d.ts'], | ||||
|   noImplicitAny: true, | ||||
|   esModuleInterop: true, | ||||
|   useDefineForClassFields: false, | ||||
|   verbatimModuleSyntax: true, | ||||
|   baseUrl: './', | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * TsBuild class for handling TypeScript compilation | ||||
|  */ | ||||
| export class TsBuild { | ||||
|   private fileNames: string[] = []; | ||||
|   private options: plugins.typescript.CompilerOptions; | ||||
|   private argvArg?: any; | ||||
|  | ||||
|   /** | ||||
|    * Create a new TsBuild instance | ||||
|    */ | ||||
|   constructor( | ||||
|     fileNames: string[] = [],  | ||||
|     customOptions: CompilerOptions = {},  | ||||
|     argvArg?: any | ||||
|   ) { | ||||
|     this.fileNames = fileNames; | ||||
|     this.argvArg = argvArg; | ||||
|     this.options = this.mergeCompilerOptions(customOptions, argvArg); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Helper function to read and process tsconfig.json | ||||
|    */ | ||||
|   private getTsConfigOptions(): CompilerOptions { | ||||
|     console.log(`looking at tsconfig.json at ${paths.cwd}`); | ||||
|     const tsconfig = plugins.smartfile.fs.toObjectSync(plugins.path.join(paths.cwd, 'tsconfig.json')); | ||||
|     const returnObject: CompilerOptions = {}; | ||||
|      | ||||
|     if (!tsconfig || !tsconfig.compilerOptions) { | ||||
|       return returnObject; | ||||
|     } | ||||
|      | ||||
|     if (tsconfig.compilerOptions.baseUrl) { | ||||
|       console.log('baseUrl found in tsconfig.json'); | ||||
|       returnObject.baseUrl = tsconfig.compilerOptions.baseUrl; | ||||
|     } | ||||
|      | ||||
|     if (tsconfig.compilerOptions.paths) { | ||||
|       console.log('paths found in tsconfig.json'); | ||||
|       returnObject.paths = tsconfig.compilerOptions.paths; | ||||
|       for (const path of Object.keys(tsconfig.compilerOptions.paths)) { | ||||
|         returnObject.paths[path][0] = returnObject.paths[path][0].replace('./ts_', './dist_ts_'); | ||||
|       } | ||||
|     } | ||||
|      | ||||
|     return returnObject; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Process command line arguments and return applicable compiler options | ||||
|    */ | ||||
|   private getCommandLineOptions(argvArg?: any): CompilerOptions { | ||||
|     if (!argvArg) return {}; | ||||
|      | ||||
|     const options: CompilerOptions = {}; | ||||
|      | ||||
|     if (argvArg.skiplibcheck) { | ||||
|       options.skipLibCheck = true; | ||||
|     } | ||||
|      | ||||
|     if (argvArg.allowimplicitany) { | ||||
|       options.noImplicitAny = false; | ||||
|     } | ||||
|      | ||||
|     if (argvArg.commonjs) { | ||||
|       options.module = plugins.typescript.ModuleKind.CommonJS; | ||||
|       options.moduleResolution = plugins.typescript.ModuleResolutionKind.NodeJs; | ||||
|     } | ||||
|      | ||||
|     return options; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Merges compilerOptions with the default compiler options | ||||
|    */ | ||||
|   public mergeCompilerOptions( | ||||
|     customTsOptions: CompilerOptions = {}, | ||||
|     argvArg?: any | ||||
|   ): CompilerOptions { | ||||
|     // create merged options | ||||
|     const mergedOptions: CompilerOptions = { | ||||
|       ...compilerOptionsDefault, | ||||
|       ...customTsOptions, | ||||
|       ...this.getCommandLineOptions(argvArg), | ||||
|       ...this.getTsConfigOptions(), | ||||
|     }; | ||||
|  | ||||
|     console.log(mergedOptions); | ||||
|     return mergedOptions; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Helper function to handle and log TypeScript diagnostics | ||||
|    */ | ||||
|   private handleDiagnostics(diagnostics: readonly plugins.typescript.Diagnostic[]): boolean { | ||||
|     let hasErrors = false; | ||||
|      | ||||
|     diagnostics.forEach((diagnostic) => { | ||||
|       hasErrors = true; | ||||
|       if (diagnostic.file) { | ||||
|         const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); | ||||
|         const message = plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); | ||||
|         console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); | ||||
|       } else { | ||||
|         console.log( | ||||
|           `${plugins.typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}` | ||||
|         ); | ||||
|       } | ||||
|     }); | ||||
|      | ||||
|     return hasErrors; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Creates a TypeScript program from file names and options | ||||
|    */ | ||||
|   private createProgram( | ||||
|     options: plugins.typescript.CompilerOptions = this.options | ||||
|   ): plugins.typescript.Program { | ||||
|     return plugins.typescript.createProgram(this.fileNames, options); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Set file names to be compiled | ||||
|    */ | ||||
|   public setFileNames(fileNames: string[]): void { | ||||
|     this.fileNames = fileNames; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Set compiler options | ||||
|    */ | ||||
|   public setOptions(options: CompilerOptions): void { | ||||
|     this.options = { ...this.options, ...options }; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * The main compiler function that compiles the files | ||||
|    */ | ||||
|   public async compile(): Promise<any[]> { | ||||
|     if (this.options.skipLibCheck) { | ||||
|       console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?'); | ||||
|       console.log('You are skipping libcheck... Is that really wanted?'); | ||||
|       console.log('continuing in 5 seconds...'); | ||||
|       console.log('? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?'); | ||||
|       await plugins.smartdelay.delayFor(5000); | ||||
|     } | ||||
|      | ||||
|     console.log(`Compiling ${this.fileNames.length} files...`); | ||||
|     const done = plugins.smartpromise.defer<any[]>(); | ||||
|     const program = this.createProgram(); | ||||
|      | ||||
|     // Check for pre-emit diagnostics first | ||||
|     const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program); | ||||
|     const hasPreEmitErrors = this.handleDiagnostics(preEmitDiagnostics); | ||||
|      | ||||
|     // Only continue to emit phase if no pre-emit errors | ||||
|     if (hasPreEmitErrors) { | ||||
|       console.error('TypeScript pre-emit checks failed. Please fix the issues above.'); | ||||
|       process.exit(1); | ||||
|     } | ||||
|      | ||||
|     // If no pre-emit errors, proceed with emit | ||||
|     const emitResult = program.emit(); | ||||
|     const hasEmitErrors = this.handleDiagnostics(emitResult.diagnostics); | ||||
|  | ||||
|     const exitCode = emitResult.emitSkipped ? 1 : 0; | ||||
|     if (exitCode === 0) { | ||||
|       console.log('TypeScript emit succeeded!'); | ||||
|       done.resolve(emitResult.emittedFiles); | ||||
|     } else { | ||||
|       console.error('TypeScript emit failed. Please investigate!'); | ||||
|       process.exit(exitCode); | ||||
|     } | ||||
|  | ||||
|     return done.promise; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Function to check if files can be emitted without actually emitting them | ||||
|    */ | ||||
|   public async checkEmit(): Promise<boolean> { | ||||
|     console.log(`Checking if ${this.fileNames.length} files can be emitted...`); | ||||
|      | ||||
|     // Create a program with noEmit option | ||||
|     const program = this.createProgram({ | ||||
|       ...this.options, | ||||
|       noEmit: true | ||||
|     }); | ||||
|      | ||||
|     // Check for pre-emit diagnostics | ||||
|     const preEmitDiagnostics = plugins.typescript.getPreEmitDiagnostics(program); | ||||
|     const hasPreEmitErrors = this.handleDiagnostics(preEmitDiagnostics); | ||||
|      | ||||
|     // Run the emit phase but with noEmit: true to check for emit errors without producing files | ||||
|     const emitResult = program.emit(undefined, undefined, undefined, true); | ||||
|     const hasEmitErrors = this.handleDiagnostics(emitResult.diagnostics); | ||||
|      | ||||
|     const success = !hasPreEmitErrors && !hasEmitErrors && !emitResult.emitSkipped; | ||||
|      | ||||
|     if (success) { | ||||
|       console.log('TypeScript emit check passed! File can be emitted successfully.'); | ||||
|     } else { | ||||
|       console.error('TypeScript emit check failed. Please fix the issues above.'); | ||||
|     } | ||||
|      | ||||
|     return success; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Merges compilerOptions with the default compiler options (backward compatibility) | ||||
|  */ | ||||
| export const mergeCompilerOptions = ( | ||||
|   customTsOptions: CompilerOptions, | ||||
|   argvArg?: any | ||||
| ): CompilerOptions => { | ||||
|   const tsBuild = new TsBuild(); | ||||
|   return tsBuild.mergeCompilerOptions(customTsOptions, argvArg); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * The internal main compiler function that compiles the files (backward compatibility) | ||||
|  */ | ||||
| export const compiler = async ( | ||||
|   fileNames: string[], | ||||
|   options: plugins.typescript.CompilerOptions, | ||||
|   argvArg?: any | ||||
| ): Promise<any[]> => { | ||||
|   const tsBuild = new TsBuild(fileNames, options, argvArg); | ||||
|   return tsBuild.compile(); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Function to check if a TypeScript file can be emitted without actually emitting it (backward compatibility) | ||||
|  */ | ||||
| export const emitCheck = async ( | ||||
|   fileNames: string[], | ||||
|   options: plugins.typescript.CompilerOptions = {}, | ||||
|   argvArg?: any | ||||
| ): Promise<boolean> => { | ||||
|   const tsBuild = new TsBuild(fileNames, options, argvArg); | ||||
|   return tsBuild.checkEmit(); | ||||
| }; | ||||
| @@ -1,10 +1,10 @@ | ||||
| import * as plugins from './plugins.js'; | ||||
| import type { CompilerOptions, ScriptTarget, ModuleKind } from 'typescript'; | ||||
| import { compiler, mergeCompilerOptions, emitCheck } from './tsbuild.classes.compiler.js'; | ||||
| import { compiler, mergeCompilerOptions, emitCheck } from './tsbuild.classes.tsbuild.js'; | ||||
|  | ||||
| export type { CompilerOptions, ScriptTarget, ModuleKind }; | ||||
|  | ||||
| export * from './tsbuild.classes.compiler.js'; | ||||
| export * from './tsbuild.classes.tsbuild.js'; | ||||
|  | ||||
| /** | ||||
|  * compile am array of absolute file paths | ||||
|   | ||||
		Reference in New Issue
	
	Block a user