1
1
import path from 'node:path'
2
2
import fs from 'node:fs'
3
3
import { performance } from 'node:perf_hooks'
4
+ import type { Session } from 'node:inspector'
4
5
import { cac } from 'cac'
5
6
import colors from 'picocolors'
6
7
import type { BuildOptions } from './build'
7
8
import type { ServerOptions } from './server'
8
9
import type { LogLevel } from './logger'
9
10
import { createLogger } from './logger'
10
11
import { VERSION } from './constants'
12
+ import { bindShortcuts } from './shortcuts'
11
13
import { resolveConfig } from '.'
12
14
13
15
const cli = cac ( 'vite' )
@@ -30,25 +32,34 @@ interface GlobalCLIOptions {
30
32
force ?: boolean
31
33
}
32
34
33
- export const stopProfiler = ( log : ( message : string ) => void ) : void => {
34
- // @ts -ignore
35
- const profileSession = global . __vite_profile_session
36
- if ( profileSession ) {
37
- profileSession . post ( 'Profiler.stop' , ( err : any , { profile } : any ) => {
35
+ // @ts -ignore
36
+ let profileSession : Session | undefined = global . __vite_profile_session
37
+ let profileCount = 0
38
+
39
+ export const stopProfiler = (
40
+ log : ( message : string ) => void ,
41
+ ) : void | Promise < void > => {
42
+ if ( ! profileSession ) return
43
+ return new Promise ( ( res , rej ) => {
44
+ profileSession ! . post ( 'Profiler.stop' , ( err : any , { profile } : any ) => {
38
45
// Write profile to disk, upload, etc.
39
46
if ( ! err ) {
40
- const outPath = path . resolve ( './vite-profile.cpuprofile' )
47
+ const outPath = path . resolve (
48
+ `./vite-profile-${ profileCount ++ } .cpuprofile` ,
49
+ )
41
50
fs . writeFileSync ( outPath , JSON . stringify ( profile ) )
42
51
log (
43
52
colors . yellow (
44
53
`CPU profile written to ${ colors . white ( colors . dim ( outPath ) ) } ` ,
45
54
) ,
46
55
)
56
+ profileSession = undefined
57
+ res ( )
47
58
} else {
48
- throw err
59
+ rej ( err )
49
60
}
50
61
} )
51
- }
62
+ } )
52
63
}
53
64
54
65
const filterDuplicateOptions = < T extends object > ( options : T ) => {
148
159
)
149
160
150
161
server . printUrls ( )
151
- stopProfiler ( ( message ) => server . config . logger . info ( ` ${ message } ` ) )
162
+ bindShortcuts ( server , {
163
+ print : true ,
164
+ customShortcuts : [
165
+ profileSession && {
166
+ key : 'p' ,
167
+ description : 'start/stop the profiler' ,
168
+ async action ( server ) {
169
+ if ( profileSession ) {
170
+ await stopProfiler ( server . config . logger . info )
171
+ } else {
172
+ const inspector = await import ( 'node:inspector' ) . then (
173
+ ( r ) => r . default ,
174
+ )
175
+ await new Promise < void > ( ( res ) => {
176
+ profileSession = new inspector . Session ( )
177
+ profileSession . connect ( )
178
+ profileSession . post ( 'Profiler.enable' , ( ) => {
179
+ profileSession ! . post ( 'Profiler.start' , ( ) => {
180
+ server . config . logger . info ( 'Profiler started' )
181
+ res ( )
182
+ } )
183
+ } )
184
+ } )
185
+ }
186
+ } ,
187
+ } ,
188
+ ] ,
189
+ } )
152
190
} catch ( e ) {
153
191
const logger = createLogger ( options . logLevel )
154
192
logger . error ( colors . red ( `error when starting dev server:\n${ e . stack } ` ) , {
0 commit comments