Skip to content

Commit 3d16e4c

Browse files
committed
feat(build): report total build time
1 parent 79a829d commit 3d16e4c

3 files changed

Lines changed: 49 additions & 2 deletions

File tree

‎packages/nuxt-cli/src/commands/build.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import colors from 'picocolors'
77

88
import{showBanner}from'../utils/banner'
99
import{overrideEnv}from'../utils/env'
10+
import{formatDuration}from'../utils/formatting'
1011
import{clearBuildDir}from'../utils/fs'
1112
import{loadKit}from'../utils/kit'
1213
import{acquireLock,formatLockError}from'../utils/lockfile'
@@ -39,6 +40,8 @@ export default defineCommand({
3940
asyncrun(ctx){
4041
overrideEnv('production')
4142

43+
conststart=Date.now()
44+
4245
constcwd=resolve(ctx.args.cwd||ctx.args.rootDir)
4346

4447
constprofileArg=ctx.args.profile
@@ -127,10 +130,10 @@ export default defineCommand({
127130
// TODO: revisit later if/when nuxt build --prerender will output hybrid
128131
constdir=nitro?.options.output.publicDir
129132
constpublicDir=dir ? relative(process.cwd(),dir) : '.output/public'
130-
outro(`✨ You can now deploy ${colors.cyan(publicDir)} to any static hosting!`)
133+
outro(`✨ You can now deploy ${colors.cyan(publicDir)} to any static hosting!${colors.gray(`(${formatDuration(Date.now()-start)})`)}`)
131134
}
132135
else{
133-
outro('✨ Build complete!')
136+
outro(`✨ Build complete in ${colors.cyan(formatDuration(Date.now()-start))}!`)
134137
}
135138
}
136139
finally{

‎packages/nuxt-cli/src/utils/formatting.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,22 @@ export function formatInfoBox(infoObj: Record<string, string | undefined>): stri
9797

9898
returnboxStr
9999
}
100+
101+
/**
102+
* Format an elapsed duration in milliseconds for display, using `ms` below a
103+
* second and seconds (or minutes and seconds) above it.
104+
*/
105+
exportfunctionformatDuration(ms: number): string{
106+
if(ms<1000){
107+
return`${Math.round(ms)}ms`
108+
}
109+
110+
consttotalSeconds=ms/1000
111+
if(totalSeconds<60){
112+
return`${Number(totalSeconds.toFixed(totalSeconds<10 ? 2 : 1))}s`
113+
}
114+
115+
constminutes=Math.floor(totalSeconds/60)
116+
constseconds=Math.round(totalSeconds-minutes*60)
117+
returnseconds ? `${minutes}m ${seconds}s` : `${minutes}m`
118+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import{describe,expect,it}from'vitest'
2+
3+
import{formatDuration}from'../../../src/utils/formatting'
4+
5+
describe('formatDuration',()=>{
6+
it('should render sub-second durations in milliseconds',()=>{
7+
expect(formatDuration(0)).toBe('0ms')
8+
expect(formatDuration(12.4)).toBe('12ms')
9+
expect(formatDuration(999)).toBe('999ms')
10+
})
11+
12+
it('should render seconds above a second',()=>{
13+
expect(formatDuration(1000)).toBe('1s')
14+
expect(formatDuration(1234)).toBe('1.23s')
15+
expect(formatDuration(9999)).toBe('10s')
16+
expect(formatDuration(12_300)).toBe('12.3s')
17+
expect(formatDuration(59_000)).toBe('59s')
18+
})
19+
20+
it('should render minutes and seconds above a minute',()=>{
21+
expect(formatDuration(60_000)).toBe('1m')
22+
expect(formatDuration(90_000)).toBe('1m 30s')
23+
expect(formatDuration(3_600_000)).toBe('60m')
24+
})
25+
})

0 commit comments

Comments
 (0)