Nuxt/lib/builder/webpack/plugins/progress.js

83 lines
1.8 KiB
JavaScript

const webpack = require('webpack')
const chalk = require('chalk')
const _ = require('lodash')
const sharedState = {}
const BLOCK_CHAR = '█'
module.exports = class ProgressPlugin extends webpack.ProgressPlugin {
constructor(options) {
super(options)
this.handler = (percent, msg, ...details) => this.updateProgress(percent, msg, details)
this.options = options
if (!sharedState[options.name]) {
sharedState[options.name] = {
color: options.color
}
}
this.spinner = options.spinner
}
get state() {
return sharedState[this.options.name]
}
updateProgress(percent, msg, details) {
const progress = Math.floor(percent * 100)
this.state.progress = progress
this.state.msg = msg
// Process all states
let inProgress = false
const additional = []
const bars = Object.keys(sharedState).map(name => {
const state = sharedState[name]
if (state.progress < 100) {
inProgress = true
}
const blockChar = chalk.keyword(state.color)(BLOCK_CHAR)
additional.push(`${blockChar} ${name} (${state.progress}%) `)
return {
name,
color: state.color,
progress: state.progress,
blockChar: chalk.keyword(state.color)(BLOCK_CHAR)
}
})
if (!inProgress) {
this.spinner.succeed('Compiled ' + this.options.name)
return
}
// Generate progressbars
const width = 25
const progressbars = _.range(width).fill(chalk.white(BLOCK_CHAR))
_.sortBy(bars, 'progress').reverse().forEach(bar => {
const w = bar.progress * (width / 100)
for (let i = 0; i < w; i++) {
progressbars[i] = bar.blockChar
}
})
// Update spinner
this.spinner.start()
this.spinner.text = _.startCase(msg) + ' ' + progressbars.join('') + ' ' + additional.join(' ')
}
}