11'use strict' ;
22
3- var fancyLog = require ( 'fancy-log' ) ;
4- var PluginError = require ( 'plugin-error' ) ;
5- var supportsColor = require ( 'supports-color' ) ;
6- var File = require ( 'vinyl' ) ;
7- var MemoryFileSystem = require ( 'memory-fs' ) ;
8- var nodePath = require ( 'path' ) ;
9- var through = require ( 'through' ) ;
10- var ProgressPlugin = require ( 'webpack/lib/ProgressPlugin' ) ;
11- var clone = require ( 'lodash.clone' ) ;
12-
13- var defaultStatsOptions = {
3+ const fancyLog = require ( 'fancy-log' ) ;
4+ const PluginError = require ( 'plugin-error' ) ;
5+ const supportsColor = require ( 'supports-color' ) ;
6+ const File = require ( 'vinyl' ) ;
7+ const MemoryFileSystem = require ( 'memory-fs' ) ;
8+ const nodePath = require ( 'path' ) ;
9+ const through = require ( 'through' ) ;
10+ const ProgressPlugin = require ( 'webpack/lib/ProgressPlugin' ) ;
11+ const clone = require ( 'lodash.clone' ) ;
12+
13+ const defaultStatsOptions = {
1414 colors : supportsColor . stdout . hasBasic ,
1515 hash : false ,
1616 timings : false ,
@@ -26,32 +26,42 @@ var defaultStatsOptions = {
2626 errorDetails : false
2727} ;
2828
29- var cache = { } ;
30-
3129module . exports = function ( options , wp , done ) {
32- if ( cache . wp !== wp || cache . options !== options ) {
33- cache = { } ;
30+ const cache = {
31+ options : options ,
32+ wp : wp
33+ } ;
34+
35+ options = clone ( options ) || { } ;
36+ const config = options . config || options ;
37+
38+ const isInWatchMode = ! ! options . watch ;
39+ delete options . watch ;
40+
41+ if ( typeof config === 'string' ) {
42+ config = require ( config ) ;
3443 }
3544
36- cache . options = options ;
37- cache . wp = wp ;
45+ // Webpack 4 doesn't support the `quiet` attribute, however supports
46+ // setting `stats` to a string within an array of configurations
47+ // (errors-only|minimal|none|normal|verbose) or an object with an absurd
48+ // amount of config
49+ const isSilent = options . quiet || ( typeof options . stats === 'string' && ( options . stats . match ( / ^ ( e r r o r s - o n l y | m i n i m a l | n o n e ) $ / ) ) ) ;
3850
39- options = clone ( options ) || { } ;
40- var config = options . config || options ;
4151 if ( typeof done !== 'function' ) {
42- var callingDone = false ;
52+ let callingDone = false ;
4353 done = function ( err , stats ) {
4454 if ( err ) {
4555 // The err is here just to match the API but isnt used
4656 return ;
4757 }
4858 stats = stats || { } ;
49- if ( options . quiet || callingDone ) {
59+ if ( isSilent || callingDone ) {
5060 return ;
5161 }
5262
5363 // Debounce output a little for when in watch mode
54- if ( options . watch ) {
64+ if ( isInWatchMode ) {
5565 callingDone = true ;
5666 setTimeout ( function ( ) {
5767 callingDone = false ;
@@ -63,7 +73,7 @@ module.exports = function (options, wp, done) {
6373 colors : supportsColor . stdout . hasBasic
6474 } ) ) ;
6575 } else {
66- var statsOptions = ( options && options . stats ) || { } ;
76+ const statsOptions = ( options && options . stats ) || { } ;
6777
6878 if ( typeof statsOptions === 'object' ) {
6979 Object . keys ( defaultStatsOptions ) . forEach ( function ( key ) {
@@ -72,19 +82,19 @@ module.exports = function (options, wp, done) {
7282 }
7383 } ) ;
7484 }
75- var statusLog = stats . toString ( statsOptions ) ;
85+ const statusLog = stats . toString ( statsOptions ) ;
7686 if ( statusLog ) {
7787 fancyLog ( statusLog ) ;
7888 }
7989 }
8090 } ;
8191 }
8292
83- var webpack = wp || require ( 'webpack' ) ;
84- var entry = [ ] ;
85- var entries = Object . create ( null ) ;
93+ const webpack = wp || require ( 'webpack' ) ;
94+ let entry = [ ] ;
95+ const entries = Object . create ( null ) ;
8696
87- var stream = through ( function ( file ) {
97+ const stream = through ( function ( file ) {
8898 if ( file . isNull ( ) ) {
8999 return ;
90100 }
@@ -98,10 +108,9 @@ module.exports = function (options, wp, done) {
98108 entry . push ( file . path ) ;
99109 }
100110 } , function ( ) {
101- var self = this ;
102- var handleConfig = function ( config ) {
111+ const self = this ;
112+ const handleConfig = function ( config ) {
103113 config . output = config . output || { } ;
104- config . watch = ! ! options . watch ;
105114
106115 // Determine pipe'd in entry
107116 if ( Object . keys ( entries ) . length > 0 ) {
@@ -127,9 +136,9 @@ module.exports = function (options, wp, done) {
127136 return true ;
128137 } ;
129138
130- var succeeded ;
139+ let succeeded ;
131140 if ( Array . isArray ( config ) ) {
132- for ( var i = 0 ; i < config . length ; i ++ ) {
141+ for ( let i = 0 ; i < config . length ; i ++ ) {
133142 succeeded = handleConfig ( config [ i ] ) ;
134143 if ( ! succeeded ) {
135144 return false ;
@@ -143,41 +152,62 @@ module.exports = function (options, wp, done) {
143152 }
144153
145154 // Cache compiler for future use
146- var compiler = cache . compiler || webpack ( config ) ;
155+ const compiler = cache . compiler || webpack ( config ) ;
147156 cache . compiler = compiler ;
148157
149158 const callback = function ( err , stats ) {
150159 if ( err ) {
151160 self . emit ( 'error' , new PluginError ( 'webpack-stream' , err ) ) ;
152161 return ;
153162 }
154- var jsonStats = stats ? stats . toJson ( ) || { } : { } ;
155- var errors = jsonStats . errors || [ ] ;
163+ const jsonStats = stats ? stats . toJson ( ) || { } : { } ;
164+ const errors = jsonStats . errors || [ ] ;
156165 if ( errors . length ) {
157- var errorMessage = errors . join ( '\n' ) ;
158- var compilationError = new PluginError ( 'webpack-stream' , errorMessage ) ;
159- if ( ! options . watch ) {
166+ const resolveErrorMessage = ( err ) => {
167+ if (
168+ typeof err === 'object' &&
169+ err !== null &&
170+ Object . prototype . hasOwnProperty . call ( err , 'message' )
171+ ) {
172+ return err . message ;
173+ } else if (
174+ typeof err === 'object' &&
175+ err !== null &&
176+ 'toString' in err &&
177+ err . toString ( ) !== '[object Object]'
178+ ) {
179+ return err . toString ( ) ;
180+ } else if ( Array . isArray ( err ) ) {
181+ return err . map ( resolveErrorMessage ) . join ( '\n' ) ;
182+ } else {
183+ return err ;
184+ }
185+ } ;
186+
187+ const errorMessage = errors . map ( resolveErrorMessage ) . join ( '\n' ) ;
188+ const compilationError = new PluginError ( 'webpack-stream' , errorMessage ) ;
189+ if ( ! isInWatchMode ) {
160190 self . emit ( 'error' , compilationError ) ;
161191 }
162192 self . emit ( 'compilation-error' , compilationError ) ;
163193 }
164- if ( ! options . watch ) {
194+ if ( ! isInWatchMode ) {
165195 self . queue ( null ) ;
166196 }
167197 done ( err , stats ) ;
168- if ( options . watch && ! options . quiet ) {
198+ if ( isInWatchMode && ! isSilent ) {
169199 fancyLog ( 'webpack is watching for changes' ) ;
170200 }
171201 } ;
172202
173- if ( options . watch ) {
174- const watchOptions = { } ;
203+ if ( isInWatchMode ) {
204+ const watchOptions = options . watchOptions || { } ;
175205 compiler . watch ( watchOptions , callback ) ;
176206 } else {
177207 compiler . run ( callback ) ;
178208 }
179209
180- var handleCompiler = function ( compiler ) {
210+ const handleCompiler = function ( compiler ) {
181211 if ( options . progress ) {
182212 ( new ProgressPlugin ( function ( percentage , msg ) {
183213 percentage = Math . floor ( percentage * 100 ) ;
@@ -189,21 +219,17 @@ module.exports = function (options, wp, done) {
189219
190220 cache . mfs = cache . mfs || new MemoryFileSystem ( ) ;
191221
192- var fs = compiler . outputFileSystem = cache . mfs ;
222+ const fs = compiler . outputFileSystem = cache . mfs ;
193223
194- var afterEmitPlugin = compiler . hooks
224+ const assetEmittedPlugin = compiler . hooks
195225 // Webpack 4
196- ? function ( callback ) { compiler . hooks . afterEmit . tapAsync ( 'WebpackStream' , callback ) ; }
226+ ? function ( callback ) { compiler . hooks . assetEmitted . tapAsync ( 'WebpackStream' , callback ) ; }
197227 // Webpack 2/3
198- : function ( callback ) { compiler . plugin ( 'after-emit ' , callback ) ; } ;
228+ : function ( callback ) { compiler . plugin ( 'asset-emitted ' , callback ) ; } ;
199229
200- afterEmitPlugin ( function ( compilation , callback ) {
201- Object . keys ( compilation . assets ) . forEach ( function ( outname ) {
202- if ( compilation . assets [ outname ] . emitted ) {
203- var file = prepareFile ( fs , compiler , outname ) ;
204- self . queue ( file ) ;
205- }
206- } ) ;
230+ assetEmittedPlugin ( function ( outname , _ , callback ) {
231+ const file = prepareFile ( fs , compiler , outname ) ;
232+ self . queue ( file ) ;
207233 callback ( ) ;
208234 } ) ;
209235 } ;
@@ -215,10 +241,23 @@ module.exports = function (options, wp, done) {
215241 } else {
216242 handleCompiler ( compiler ) ;
217243 }
244+
245+ if ( options . watch && ! isSilent ) {
246+ const watchRunPlugin = compiler . hooks
247+ // Webpack 4
248+ ? callback => compiler . hooks . watchRun . tapAsync ( 'WebpackInfo' , callback )
249+ // Webpack 2/3
250+ : callback => compiler . plugin ( 'watch-run' , callback ) ;
251+
252+ watchRunPlugin ( ( compilation , callback ) => {
253+ fancyLog ( 'webpack compilation starting...' ) ;
254+ callback ( ) ;
255+ } ) ;
256+ }
218257 } ) ;
219258
220259 // If entry point manually specified, trigger that
221- var hasEntry = Array . isArray ( config )
260+ const hasEntry = Array . isArray ( config )
222261 ? config . some ( function ( c ) { return c . entry ; } )
223262 : config . entry ;
224263 if ( hasEntry ) {
@@ -229,14 +268,14 @@ module.exports = function (options, wp, done) {
229268} ;
230269
231270function prepareFile ( fs , compiler , outname ) {
232- var path = fs . join ( compiler . outputPath , outname ) ;
271+ let path = fs . join ( compiler . outputPath , outname ) ;
233272 if ( path . indexOf ( '?' ) !== - 1 ) {
234273 path = path . split ( '?' ) [ 0 ] ;
235274 }
236275
237- var contents = fs . readFileSync ( path ) ;
276+ const contents = fs . readFileSync ( path ) ;
238277
239- var file = new File ( {
278+ const file = new File ( {
240279 base : compiler . outputPath ,
241280 path : nodePath . join ( compiler . outputPath , outname ) ,
242281 contents : contents
0 commit comments