import { BuildOptions } from 'esbuild' import { ParsedCommandLine, ScriptTarget, ModuleKind } from 'typescript' import { CliArgs } from './interfaces' /** * transform tsconfig to esbuild config * key: keyof TransformOptions */ export class ConfigConverter { private cwd: string private parsedCommandLine: ParsedCommandLine private esbuildConfig: BuildOptions = { bundle: false, } public constructor({ cwd, parsedCommandLine, }: { cwd: string parsedCommandLine: ParsedCommandLine }) { this.cwd = cwd this.parsedCommandLine = parsedCommandLine } public mergeCliArgs(args: CliArgs = {}) { const cliEsbuildOptions = this.cliArgsToEsbuildOptions(args) this.esbuildConfig = { ...this.esbuildConfig, ...cliEsbuildOptions } return this } public convert() { this.esbuildConfig.entryPoints = this.transformEntryPoints() this.esbuildConfig.outdir = this.transformOutDir() this.esbuildConfig.sourcemap = this.transformSourcemap() this.esbuildConfig.target = this.transformTarget() this.esbuildConfig.format = this.transformFormat() return this.esbuildConfig } private cliArgsToEsbuildOptions(args: CliArgs): BuildOptions { const options: BuildOptions = {} if (args.watch) options.watch = true return options } private transformEntryPoints(): BuildOptions['entryPoints'] { return this.parsedCommandLine.fileNames } private transformOutDir(): BuildOptions['outdir'] { return this.parsedCommandLine.options.outDir || this.cwd // rootDir } private transformFormat(): BuildOptions['format'] { const explicit = this.parsedCommandLine.options?.module if (explicit !== undefined) { const moduleKey = ModuleKind[explicit] if (moduleKey === 'CommonJS') { return 'cjs' } } return 'esm' } private transformTarget(): BuildOptions['target'] { const explicit = this.parsedCommandLine.options?.target if (explicit) return [ScriptTarget[explicit].toLowerCase()] /** * tsc default to ES3 * but esbuild do not support es3, we choose es6 for best compability. * https://esbuild.github.io/api/#target */ return ['es2015'] } private transformSourcemap(): BuildOptions['sourcemap'] { if (this.parsedCommandLine.options.inlineSourceMap) return 'inline' if (this.parsedCommandLine.options.sourceMap) return 'external' return undefined } }