1
1
import webpack from 'webpack' ;
2
2
import env from 'std-env' ;
3
+ import prettyTime from 'pretty-time' ;
3
4
4
5
import { LogReporter , BarsReporter , ProfileReporter } from './reporters' ;
5
6
import Profile from './profile' ;
6
7
import { startCase } from './utils' ;
7
- import { consola } from './utils/cli' ;
8
8
import { parseRequest } from './utils/request' ;
9
9
10
+ // Use bars when possible as default
11
+ const useBars = ! ( env . ci || env . test || ! env . tty ) ;
12
+
10
13
// Default plugin options
11
14
const DEFAULTS = {
12
15
name : 'webpack' ,
@@ -15,11 +18,22 @@ const DEFAULTS = {
15
18
stream : process . stdout ,
16
19
reporters : [ ] ,
17
20
reporter : null ,
18
- log : ! ! env . minimalCLI ,
19
- bars : ! env . minimalCLI ,
21
+ log : ! useBars ,
22
+ bars : useBars ,
23
+ } ;
24
+
25
+ // Default state object
26
+ const DEFAULT_STATE = {
27
+ start : null ,
28
+ progress : - 1 ,
29
+ message : '' ,
30
+ details : [ ] ,
31
+ request : null ,
32
+ stats : null ,
33
+ hasErrors : false ,
20
34
} ;
21
35
22
- // Mapping from name => { isRunning, details, progress, msg, request }
36
+ // Mapping from name => State
23
37
const globalStates = { } ;
24
38
25
39
export default class WebpackBarPlugin extends webpack . ProgressPlugin {
@@ -30,14 +44,14 @@ export default class WebpackBarPlugin extends webpack.ProgressPlugin {
30
44
this . name = startCase ( options . name ) ;
31
45
32
46
// this.handler will be called by webpack.ProgressPlugin
33
- this . handler = ( percent , msg , ...details ) =>
34
- this . updateProgress ( percent , msg , details ) ;
47
+ this . handler = ( percent , message , ...details ) =>
48
+ this . updateProgress ( percent , message , details ) ;
35
49
36
50
// Keep our state in shared ojbect
37
51
this . states = globalStates ;
38
52
if ( ! this . states [ this . name ] ) {
39
53
this . states [ this . name ] = {
40
- isRunning : false ,
54
+ ... DEFAULT_STATE ,
41
55
color : this . options . color ,
42
56
profile : this . options . profile ? new Profile ( this . name ) : null ,
43
57
} ;
@@ -70,71 +84,81 @@ export default class WebpackBarPlugin extends webpack.ProgressPlugin {
70
84
try {
71
85
reporter [ fn ] ( this , payload ) ;
72
86
} catch ( e ) {
73
- consola . error ( e ) ;
87
+ process . stdout . write ( e . stack + '\n' ) ;
74
88
}
75
89
}
76
90
}
77
91
}
78
92
79
- hasRunning ( ) {
80
- return Object . values ( this . states ) . some ( ( state ) => state . isRunning ) ;
93
+ get hasRunning ( ) {
94
+ return Object . values ( this . states ) . some ( ( state ) => state . progress !== 100 ) ;
81
95
}
82
96
83
- hasErrors ( ) {
84
- return Object . values ( this . states ) . some (
85
- ( state ) => state . stats && state . stats . hasErrors ( )
86
- ) ;
97
+ get hasErrors ( ) {
98
+ return Object . values ( this . states ) . some ( ( state ) => state . hasErrors ) ;
87
99
}
88
100
89
101
apply ( compiler ) {
90
102
super . apply ( compiler ) ;
91
103
92
- const hook = ( stats ) => {
93
- this . state . stats = stats ;
94
- try {
95
- if ( ! this . hasRunning ( ) ) {
96
- this . callReporters ( 'done' ) ;
97
- }
98
- } catch ( e ) {
99
- consola . error ( e ) ;
104
+ // Hook helper for webpack 3 + 4 support
105
+ function hook ( hookName , fn ) {
106
+ if ( compiler . hooks ) {
107
+ compiler . hooks [ hookName ] . tap ( 'WebpackBar:' + hookName , fn ) ;
108
+ } else {
109
+ compiler . plugin ( hookName , fn ) ;
100
110
}
101
- } ;
102
-
103
- if ( compiler . hooks ) {
104
- compiler . hooks . done . tap ( 'WebpackBar' , hook ) ;
105
- } else {
106
- compiler . plugin ( 'done' , hook ) ;
107
111
}
112
+
113
+ // Adds a hook right before compiler.run() is executed
114
+ hook ( 'beforeCompile' , ( ) => {
115
+ Object . assign ( this . state , {
116
+ ...DEFAULT_STATE ,
117
+ start : process . hrtime ( ) ,
118
+ _allDoneCalled : false ,
119
+ } ) ;
120
+
121
+ this . callReporters ( 'beforeRun' ) ;
122
+ } ) ;
123
+
124
+ // Compilation has completed
125
+ hook ( 'done' , ( stats ) => {
126
+ const time = prettyTime ( process . hrtime ( this . state . start ) , 2 ) ;
127
+ const hasErrors = stats . hasErrors ( ) ;
128
+ const status = hasErrors ? 'with some errors' : 'succesfuly' ;
129
+
130
+ Object . assign ( this . state , {
131
+ ...DEFAULT_STATE ,
132
+ stats,
133
+ progress : 100 ,
134
+ message : `Compiled ${ status } in ${ time } ` ,
135
+ hasErrors,
136
+ } ) ;
137
+
138
+ this . callReporters ( 'progress' ) ;
139
+ this . callReporters ( 'done' ) ;
140
+
141
+ if ( ! this . hasRunning ) {
142
+ this . callReporters ( 'beforeAllDone' ) ;
143
+ this . callReporters ( 'allDone' ) ;
144
+ }
145
+ } ) ;
108
146
}
109
147
110
- updateProgress ( percent , msg , details = [ ] ) {
148
+ updateProgress ( percent = 0 , message = '' , details = [ ] ) {
111
149
const progress = Math . floor ( percent * 100 ) ;
112
- const isRunning = progress < 100 ;
113
-
114
- const wasRunning = this . state . isRunning ;
115
150
116
151
Object . assign ( this . state , {
117
- details,
118
152
progress,
119
- msg : isRunning && msg ? msg : '' ,
153
+ message : message || '' ,
154
+ details,
120
155
request : parseRequest ( details [ 2 ] ) ,
121
- elapsed : process . hrtime ( this . state . start ) ,
122
- isRunning,
123
156
} ) ;
124
157
125
- if ( ! wasRunning && isRunning ) {
126
- // Started
127
- this . state . start = process . hrtime ( ) ;
128
- this . callReporters ( 'compiling' ) ;
129
- } else if ( wasRunning && ! isRunning ) {
130
- // Finished
131
- this . callReporters ( 'compiled' ) ;
132
- }
133
-
134
158
if ( this . options . profile ) {
135
159
this . state . profile . onRequest ( this . state . request ) ;
136
160
}
137
161
138
- this . callReporters ( 'update ' ) ;
162
+ this . callReporters ( 'progress ' ) ;
139
163
}
140
164
}
0 commit comments