Created
February 14, 2023 11:28
-
-
Save bytemain/8038485235fd945c29bf6e38c5a5daee to your computer and use it in GitHub Desktop.
Build your Typescript Node.js projects using blazing fast esbuild
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
#!/usr/bin/env tsx | |
import { config } from 'dotenv'; | |
config(); | |
import { context as createContext, Plugin } from 'esbuild'; | |
import ts from 'typescript'; | |
import { build } from 'esbuild'; | |
import mri from 'mri'; | |
const cwd = process.cwd(); | |
const argv = mri(process.argv.slice(2)); | |
console.log(argv); | |
function getTSConfig(_tsConfigFile = 'tsconfig.json') { | |
const tsConfigFile = ts.findConfigFile(cwd, ts.sys.fileExists, _tsConfigFile); | |
if (!tsConfigFile) { | |
throw new Error(`tsconfig.json not found in the current directory! ${cwd}`); | |
} | |
const configFile = ts.readConfigFile(tsConfigFile, ts.sys.readFile); | |
const tsConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, cwd); | |
return { tsConfig, tsConfigFile }; | |
} | |
type TSConfig = ReturnType<typeof getTSConfig>['tsConfig']; | |
function esBuildSourceMapOptions(tsConfig: TSConfig) { | |
const { sourceMap, inlineSources, inlineSourceMap } = tsConfig.options; | |
// inlineSources requires either inlineSourceMap or sourceMap | |
if (inlineSources && !inlineSourceMap && !sourceMap) { | |
return false; | |
} | |
// Mutually exclusive in tsconfig | |
if (sourceMap && inlineSourceMap) { | |
return false; | |
} | |
if (inlineSourceMap) { | |
return 'inline'; | |
} | |
return sourceMap; | |
} | |
async function main() { | |
const { tsConfig, tsConfigFile } = getTSConfig(); | |
const outdir = tsConfig.options.outDir || 'dist'; | |
const srcFiles = [...tsConfig.fileNames]; | |
const sourcemap = esBuildSourceMapOptions(tsConfig); | |
const target: string = tsConfig?.raw?.compilerOptions?.target || 'es2015'; | |
await build({}); | |
const context = await createContext({ | |
bundle: argv.bundle || false, | |
format: argv.format || 'cjs', | |
platform: 'node', | |
minify: false, | |
color: true, | |
outdir, | |
entryPoints: srcFiles, | |
sourcemap, | |
target: target.toLowerCase(), | |
tsconfig: tsConfigFile, | |
}); | |
if (argv['watch']) { | |
await context.watch(); | |
} else { | |
await context.rebuild().then((v) => { | |
console.log(`build ~ result`, v); | |
context.dispose(); | |
}); | |
} | |
} | |
console.time('Built in'); | |
main() | |
.then(() => { | |
console.timeEnd('Built in'); | |
process.exit(0); | |
}) | |
.catch((err) => { | |
console.error(err); | |
process.exit(1); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment