/
cli.ts
177 lines (168 loc) · 4.99 KB
/
cli.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import { cac } from 'cac'
import chalk from 'chalk'
import { BuildOptions } from './build'
import { ServerOptions } from './server'
import { createLogger, LogLevel } from './logger'
import { resolveConfig } from '.'
const cli = cac('vite')
// global options
interface GlobalCLIOptions {
'--'?: string[]
debug?: boolean | string
d?: boolean | string
filter?: string
f?: string
config?: string
c?: boolean | string
root?: string
r?: string
mode?: string
m?: string
logLevel?: LogLevel
l?: LogLevel
clearScreen?: boolean
}
/**
* removing global flags before passing as command specific sub-configs
*/
function cleanOptions(options: GlobalCLIOptions) {
const ret = { ...options }
delete ret['--']
delete ret.debug
delete ret.d
delete ret.filter
delete ret.f
delete ret.config
delete ret.c
delete ret.root
delete ret.r
delete ret.mode
delete ret.m
delete ret.logLevel
delete ret.l
delete ret.clearScreen
return ret
}
cli
.option('-c, --config <file>', `[string] use specified config file`)
.option('-r, --root <path>', `[string] use specified root directory`)
.option('-l, --logLevel <level>', `[string] silent | error | warn | all`)
.option('--clearScreen', `[boolean] allow/disable clear screen when logging`)
.option('-d, --debug [feat]', `[string | boolean] show debug logs`)
.option('-f, --filter <filter>', `[string] filter debug logs`)
// dev
cli
.command('[root]') // default command
.alias('serve')
.option('--host <host>', `[string] specify hostname`)
.option('--port <port>', `[number] specify port`)
.option('--https', `[boolean] use TLS + HTTP/2`)
.option('--open [browser]', `[boolean | string] open browser on startup`)
.option('--cors', `[boolean] enable CORS`)
.option('--strictPort', `[boolean] exit if specified port is already in use`)
.option('-m, --mode <mode>', `[string] set env mode`)
.option(
'--force',
`[boolean] force the optimizer to ignore the cache and re-bundle`
)
.action(async (root: string, options: ServerOptions & GlobalCLIOptions) => {
// output structure is preserved even after bundling so require()
// is ok here
const { createServer } = await import('./server')
try {
const server = await createServer({
root,
mode: options.mode,
configFile: options.config,
logLevel: options.logLevel,
clearScreen: options.clearScreen,
server: cleanOptions(options) as ServerOptions
})
await server.listen()
} catch (e) {
createLogger(options.logLevel).error(
chalk.red(`error when starting dev server:\n${e.stack}`)
)
process.exit(1)
}
})
// build
cli
.command('build [root]')
.option('--base <path>', `[string] public base path (default: /)`)
.option('--target <target>', `[string] transpile target (default: 'modules')`)
.option('--outDir <dir>', `[string] output directory (default: dist)`)
.option(
'--assetsDir <dir>',
`[string] directory under outDir to place assets in (default: _assets)`
)
.option(
'--assetsInlineLimit <number>',
`[number] static asset base64 inline threshold in bytes (default: 4096)`
)
.option('--ssr', `[boolean] build for server-side rendering`)
.option(
'--sourcemap',
`[boolean] output source maps for build (default: false)`
)
.option(
'--minify [minifier]',
`[boolean | "terser" | "esbuild"] enable/disable minification, ` +
`or specify minifier to use (default: terser)`
)
.option('--manifest', `[boolean] emit build manifest json`)
.option(
'--emptyOutDir',
`[boolean] force empty outDir when it's outside of root`
)
.option('-m, --mode <mode>', `[string] set env mode`)
.action(async (root: string, options: BuildOptions & GlobalCLIOptions) => {
const { build } = await import('./build')
try {
await build({
root,
mode: options.mode,
configFile: options.config,
logLevel: options.logLevel,
clearScreen: options.clearScreen,
build: cleanOptions(options) as BuildOptions
})
} catch (e) {
createLogger(options.logLevel).error(
chalk.red(`error during build:\n${e.stack}`)
)
process.exit(1)
}
})
// optimize
cli
.command('optimize [root]')
.option(
'--force',
`[boolean] force the optimizer to ignore the cache and re-bundle`
)
.action(
async (root: string, options: { force?: boolean } & GlobalCLIOptions) => {
const { optimizeDeps } = await import('./optimizer')
try {
const config = await resolveConfig(
{
root,
configFile: options.config,
logLevel: options.logLevel
},
'build',
'development'
)
await optimizeDeps(config, options.force, true)
} catch (e) {
createLogger(options.logLevel).error(
chalk.red(`error when optimizing deps:\n${e.stack}`)
)
process.exit(1)
}
}
)
cli.help()
cli.version(require('../../package.json').version)
cli.parse()