/
cli-main.ts
138 lines (132 loc) · 4.58 KB
/
cli-main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import { readFileSync } from 'fs'
import { join } from 'path'
import { cac } from 'cac'
import flat from 'flat'
import { Format, Options } from '.'
function ensureArray(input: string): string[] {
return Array.isArray(input) ? input : input.split(',')
}
export async function main(options: Options = {}) {
const cli = cac('tsup')
cli
.command('[...files]', 'Bundle files', {
ignoreOptionDefaultValue: true,
})
.option('-d, --out-dir <dir>', 'Output directory', { default: 'dist' })
.option('--format <format>', 'Bundle format, "cjs", "iife", "esm"', {
default: 'cjs',
})
.option('--minify', 'Minify bundle')
.option('--minify-whitespace', 'Minify whitespace')
.option('--minify-identifiers', 'Minify identifiers')
.option('--minify-syntax', 'Minify syntax')
.option(
'--keep-names',
'Keep original function and class names in minified code'
)
.option('--target <target>', 'Bundle target, "es20XX" or "esnext"', {
default: 'es2017',
})
.option('--babel', 'Transform the result with Babel')
.option(
'--legacy-output',
'Output different formats to different folder instead of using different extensions'
)
.option('--dts [entry]', 'Generate declaration file')
.option('--dts-resolve', 'Resolve externals types used for d.ts files')
.option(
'--sourcemap [option]',
'Generate sourcemap, "external", "inline", "both"'
)
.option(
'--watch [path]',
'Watch mode, if path is not specified, it watches the current folder ".". Repeat "--watch" for more than one path'
)
.option('--ignore-watch <path>', 'Ignore custom paths in watch mode')
.option(
'--onSuccess <command>',
'Execute command after successful build, specially useful for watch mode'
)
.option('--env.* <value>', 'Define compile-time env variables')
.option(
'--inject <file>',
'Replace a global variable with an import from another file'
)
.option('--define.* <value>', 'Define compile-time constants')
.option('--external <name>', 'Mark specific packages as external')
.option('--global-name <name>', 'Global variable name for iife format')
.option('--jsxFactory <jsxFactory>', 'Name of JSX factory function', {
default: 'React.createElement',
})
.option('--jsxFragment <jsxFragment>', 'Name of JSX fragment function', {
default: 'React.Fragment',
})
.option(
'--inlineDynamicImports',
'Create a single bundle that inlines dynamic imports'
)
.option('--replaceNodeEnv', 'Replace process.env.NODE_ENV')
.option('--no-splitting', 'Disable code splitting')
.option('--clean', 'Clean output directory')
.option(
'--silent',
'Suppress non-error logs (excluding "onSuccess" process output)'
)
.option('--pure <express>', 'Mark specific expressions as pure')
.option('--metafile', 'Emit esbuild metafile (a JSON file)')
.option('--platform <platform>', 'Target platform', {
default: 'node',
})
.option('--loader <ext=loader>', 'Specify the loader for a file extension')
.option('--no-config', 'Disable config file')
.action(async (files: string[], flags) => {
const { build } = await import('.')
Object.assign(options, {
...flags,
})
if (files.length > 0) {
options.entryPoints = files
}
if (flags.format) {
const format = ensureArray(flags.format) as Format[]
options.format = format
}
if (flags.external) {
const external = ensureArray(flags.external)
options.external = external
}
if (flags.dts || flags.dtsResolve) {
options.dts = {}
if (typeof flags.dts === 'string') {
options.dts.entry = flags.dts
}
if (flags.dtsResolve) {
options.dts.resolve = flags.dtsResolve
}
}
if (flags.inject) {
const inject = ensureArray(flags.inject)
options.inject = inject
}
if (flags.define) {
const define: any = flat(flags.define)
options.define = define
}
if (flags.loader) {
const loader = ensureArray(flags.loader)
options.loader = loader.reduce((result, item) => {
const parts = item.split('=')
return {
...result,
[parts[0]]: parts[1],
}
}, {})
}
await build(options)
})
cli.help()
const pkgPath = join(__dirname, '../package.json')
cli.version(JSON.parse(readFileSync(pkgPath, 'utf8')).version)
cli.parse(process.argv, { run: false })
await cli.runMatchedCommand()
}