4
4
*/
5
5
const webpack = require ( 'webpack' ) ;
6
6
const path = require ( 'path' ) ;
7
- const spawn = require ( 'child_process' ) . spawn ;
7
+ const spawn = require ( 'child_process' ) . spawnSync ;
8
8
const fse = require ( 'fs-extra' ) ;
9
9
const chalk = require ( 'chalk' ) ;
10
10
const validateOptions = require ( 'schema-utils' ) ;
@@ -60,7 +60,7 @@ module.exports = class Plugin {
60
60
// If the user has chosen to show output, output information about the finalized
61
61
// options the plugin will use.
62
62
if ( this . options . showOutput ) {
63
- console . log ( chalk . yellow ( `${ pluginName } :` ) , 'Initializing with Options:' , this . options ) ;
63
+ console . log ( chalk . yellow ( `${ this . pluginName } :` ) , 'Initializing with Options:' , this . options ) ;
64
64
}
65
65
}
66
66
/**
@@ -192,55 +192,64 @@ module.exports = class Plugin {
192
192
* @param {string } tmpFile - The full path to the tmpFile. Used for checking whether it exists or not.
193
193
* @return {Promise } The Promise returned by the function.
194
194
*/
195
- promiseEsdoc ( cmd , esdocArgs , esdocConfigDir , tmpFile ) {
195
+ Esdoc ( cmd , esdocArgs , esdocConfigDir , tmpFile ) {
196
196
let esdocErrors = [ ] ;
197
- return new Promise ( ( resolve , reject ) => {
198
- const esdoc = spawn ( cmd , esdocArgs , {
199
- cwd : esdocConfigDir ,
200
- } ) ;
201
- // If showOutput is true, collect the socket output from esdoc, turning
202
- // the buffer into something readable.
203
- if ( this . options . showOutput ) {
204
- let received = '' ;
197
+ const esdoc = spawn ( cmd , esdocArgs , {
198
+ cwd : esdocConfigDir ,
199
+ } ) ;
205
200
206
- // Tell the user it's about to start.
207
- console . log ( chalk . yellow ( `${ pluginName } :` ) , 'Beginning output.' ) ;
201
+ // If showOutput is true, collect the socket output from esdoc, turning
202
+ // the buffer into something readable.
203
+ if ( this . options . showOutput ) {
208
204
209
- // Upon receiving data:
210
- esdoc . stdout . on ( 'data' , ( data ) => {
211
- received += data ;
212
- const messages = received . split ( '\n' ) ;
213
- if ( messages . length > 1 ) {
214
- let printed = '' ;
215
- for ( let message of messages ) {
216
- if ( message !== '' ) {
217
- let split = ( message . toString ( ) . split ( ':' ) ) ;
218
- console . log ( `${ chalk . blue ( split [ 0 ] ) } : ${ chalk . green ( split [ 1 ] ) } ` ) ;
219
- received = '' ;
220
- }
221
- }
222
- }
223
- } ) ;
224
- }
225
- // Upon an error:
226
- esdoc . stderr . on ( 'data' , ( data ) => esdocErrors . push ( data . toString ( ) ) ) ;
205
+ let received = '' ;
227
206
228
- // Upon socket close:
229
- esdoc . on ( 'close' , ( closeCode ) => {
230
- // Remove that tmp file, if one exists, and the user has chosen not to preserve it.
231
- if ( tmpFile && ! this . options . preserveTmpFile ) {
232
- console . log ( chalk . yellow ( `${ this . pluginName } :` ) , 'Removing temporary esdoc config file...' ) ;
233
- fse . unlinkSync ( tmpFile ) ;
207
+ // Tell the user it's about to start.
208
+ console . log ( chalk . yellow ( `${ this . pluginName } :` ) , 'Beginning output.' ) ;
209
+
210
+ // Show the data.
211
+ const esdocOutput = esdoc . stdout ;
212
+ received += esdocOutput ;
213
+ const messages = received . split ( '\n' ) ;
214
+ // Try to make the buffer data look nicer by coloring parts.
215
+ const setOutputPrefixColor = ( str ) => {
216
+ let prefixes = { resolve : 'cyan' , output : 'blue' , parse : 'green' } ;
217
+ let prefix = str ;
218
+ for ( const key in prefixes ) {
219
+ if ( str === key ) {
220
+ prefix = chalk [ prefixes [ key ] ] ( str ) ;
221
+ break ;
222
+ }
234
223
}
235
- if ( esdocErrors . length > 0 ) {
236
- esdocErrors . forEach ( ( value ) => console . error ( value ) ) ;
237
- reject ( new Error ( chalk . yellow ( `${ this . pluginName } :` ) , 'Exited with code ' + code ) ) ;
238
- } else {
239
- console . log ( chalk . yellow ( `${ this . pluginName } :` ) , 'Emitted files to output directory.' ) ;
240
- resolve ( true ) ;
224
+ return prefix ;
225
+ }
226
+ if ( messages . length > 1 ) {
227
+ let printed = '' ;
228
+ for ( let message of messages ) {
229
+ if ( message !== '' ) {
230
+ let split = ( message . toString ( ) . split ( ':' ) ) ;
231
+ console . log ( `${ setOutputPrefixColor ( split [ 0 ] ) } : ${ chalk . dim ( split [ 1 ] ) } ` ) ;
232
+ received = '' ;
233
+ }
241
234
}
242
- } ) ;
243
- } ) ;
235
+ }
236
+ }
237
+
238
+ // Remove that tmp file, if one exists, and the user has chosen not to preserve it.
239
+ if ( tmpFile && ! this . options . preserveTmpFile ) {
240
+ console . log ( chalk . yellow ( `${ this . pluginName } :` ) , 'Removing temporary esdoc config file...' ) ;
241
+ if ( fse . existsSync ( tmpFile ) ) {
242
+ fse . unlinkSync ( tmpFile ) ;
243
+ }
244
+ }
245
+ if ( esdoc . stderr . length > 0 ) {
246
+ console . error ( 'ERR toString' , esdoc . stderr . toString ( ) ) ;
247
+ // esdocErrors.forEach((value) => console.error(value));
248
+ return new Error ( chalk . yellow ( `${ this . pluginName } :` ) , 'Exited with code ' + esdoc . status ) ;
249
+ } else {
250
+ console . log ( chalk . yellow ( `${ this . pluginName } :` ) , 'Emitted files to output directory.' ) ;
251
+ return true ;
252
+ }
244
253
}
245
254
/**
246
255
* The apply method Webpack plugins must declare.
@@ -271,22 +280,17 @@ module.exports = class Plugin {
271
280
tmpFilepath ;
272
281
273
282
/**
274
- * Hooks into watchRun using tapAsync ().
283
+ * Hooks into emit using tap ().
275
284
*
276
- * @external {compiler.hooks.watchRun.tapAsync } https://webpack.js.org/api/compiler-hooks/#watchrun
285
+ * @external {compiler.hooks.shouldEmit } https://webpack.js.org/api/compiler-hooks/#shouldEmit
286
+ * @todo This would probably be better using the emit hook, but no matter
287
+ * do it seems like it always forces two runs when watch mode is
288
+ * started. Running ESDoc on the compile hook works, but eventually
289
+ * it would be good to do this the webpack way with compilation
290
+ * modules and chunks and stuff.
291
+ * Everything works, but watch is annoying on startup.
277
292
*/
278
- compiler . hooks . watchRun . tapAsync ( pluginName , ( compiler , callback ) => {
279
- // During the Webpack watchRun event, notify the user that the plugin is watching for changes.
280
- console . log ( chalk . yellow ( `${ pluginName } ` ) , chalk . magenta ( 'Watching for changes...' ) ) ;
281
- callback ( ) ;
282
- } ) ;
283
-
284
- /**
285
- * Hooks into emit using tapAsync().
286
- *
287
- * @external {compiler.hooks.emit.tapAsync } https://webpack.js.org/api/compiler-hooks/#emit
288
- */
289
- compiler . hooks . emit . tapAsync ( pluginName , ( compilation , callback ) => {
293
+ compiler . hooks . compilation . tap ( pluginName , ( compilation ) => {
290
294
// Let the user know ESDocPlugin is running.
291
295
console . log ( chalk . yellow ( `${ pluginName } :` ) , 'Compiling...' ) ;
292
296
@@ -366,7 +370,11 @@ module.exports = class Plugin {
366
370
esdocArgs = [ '-c' , esdocConfig ] ;
367
371
368
372
// End the emit hook.
369
- callback ( ) ;
373
+ try {
374
+ this . Esdoc ( cmd , esdocArgs , esdocConfigDir , tmpFile , obj )
375
+ } catch ( err ) {
376
+ return new Error ( pluginName , 'There was a problem running ESDoc.' ) ;
377
+ }
370
378
} ) ;
371
379
372
380
/**
@@ -375,18 +383,8 @@ module.exports = class Plugin {
375
383
* @external {compiler.hooks.done.tapAsync } https://webpack.js.org/api/compiler-hooks/#done
376
384
*/
377
385
compiler . hooks . done . tap ( pluginName , ( stats ) => {
378
- // @TODO : Really this run of ESDoc as a child process should probably happen in the emit hook,
379
- // but if it's there, watching makes emit trigger twice on startup. I'm guessing the
380
- // reason this happens is that emit finishes before the subprocess has totally exited,
381
- // so when it finally does end, the ESDoc process creates/modifies files in the plugin
382
- // output directory get created and compilation starts all over again.
383
- // I need a way to ignore the output files or directory for this plugin during watch, it
384
- // doesn't matter if something happens there.
385
- this . promiseEsdoc ( cmd , esdocArgs , esdocConfigDir , tmpFile , obj )
386
- . then ( response => {
387
- console . log ( chalk . yellow ( `${ pluginName } :` ) , 'Finished compiling.' ) ;
388
- console . log ( chalk . yellow ( `${ pluginName } :` ) , 'Total run time ' , chalk . green ( self . millisToMinutesAndSeconds ( stats . endTime - stats . startTime ) ) ) ;
389
- } )
386
+ console . log ( chalk . yellow ( `${ pluginName } :` ) , 'Finished.' ) ;
387
+ console . log ( chalk . yellow ( `${ pluginName } :` ) , 'Total run time ' , chalk . green ( self . millisToMinutesAndSeconds ( stats . endTime - stats . startTime ) ) ) ;
390
388
} ) ;
391
389
392
390
}
0 commit comments