import { ProgressPlugin , Compiler } from 'webpack' ; import { SingleBar , Options } from 'cli-progress' ; import chalk from 'chalk' ; const PROGRESS_BAR_OPTIONS = { format : ( options , params , payload ) => { const bar = options . formatBar ! ( params . progress , options ) ; const percentage = Math . round ( ( params . progress * 100 ) ) ; const detail = percentage >= 99 ? '' : chalk . white ( `- ${ payload . message }` ) ; return `${ chalk . greenBright ( '● @reskript/dev' ) } ${ bar } building (${ percentage }%) ${ detail }` ; } , formatBar : ( progress ) => { const total = 40 ; const active = Math . round ( total * progress ) ; const remaining = total - active ; return chalk . bgGreenBright ( ' ' . repeat ( active ) ) + chalk . bgWhite ( ' ' . repeat ( remaining ) ) ; } , } ; export default class ProgressBarPlugin extends ProgressPlugin { private readonly progressBar = new SingleBar ( PROGRESS_BAR_OPTIONS ) ; private working = false ; private lastPercentage = 0 ; apply ( compiler ) { this . handler = ( percentage , stage , message ) => { this . lastPercentage = percentage ; if ( this . working ) { this . progressBar . update ( Math . max ( percentage , this . lastPercentage ) , { stage , message } ) ; } } ; compiler . hooks . beforeCompile . tap ( 'progress-bar-plugin' , ( ) => { this . working = true ; this . progressBar . start ( 1 , 0 ) ; } ) ; compiler . hooks . afterEmit . tap ( 'progress-bar-plugin' , ( ) => { this . progressBar . update ( 1 ) ; this . progressBar . stop ( ) ; this . working = false ; } ) ; process . on ( 'SIGINT' , ( ) => ( this . working = false ) ) ; super . apply ( compiler ) ; } }