UNPKG

2.81 kBJavaScriptView Raw
1const
2 { ProgressPlugin } = require('webpack'),
3 throttle = require('lodash.throttle'),
4 { green, grey } = require('chalk'),
5 log = require('../helpers/logger')('app:progress'),
6 logUpdate = require('log-update'),
7 ms = require('ms')
8
9const
10 isMinimalTerminal = require('../helpers/is-minimal-terminal'),
11 logLine = isMinimalTerminal
12 ? () => {}
13 : logUpdate.create(process.stdout, { showCursor: true })
14
15const
16 compilations = {},
17 barLength = 25,
18 barItems = Array.apply(null, { length: barLength })
19
20let maxLengthName = 0
21
22function isRunningGlobally () {
23 return Object.values(compilations).find(c => c.running) !== void 0
24}
25
26function renderBar (progress, color) {
27 const width = progress * (barLength / 100)
28
29 return barItems
30 .map((_, index) => index < width ? '█' : ' ')
31 .join('')
32}
33
34function printState () {
35 const lines = Object.values(compilations).map(state => {
36 return [
37 ' ' + green( state.name.padEnd(maxLengthName) + ' ' + renderBar(state.progress)),
38 state.msg,
39 `[${state.progress}%]`.padStart(4),
40 state.running
41 ? grey(state.details
42 ? [ state.details[0], state.details[1] ].filter(s => s).join(' ')
43 : ''
44 )
45 : state.doneStamp
46 ].filter(m => m).join(' ') + '\n'
47 })
48
49 logLine('\n' + lines.join(''))
50}
51
52const render = throttle(printState, 200)
53
54module.exports = class WebpackProgress extends ProgressPlugin {
55 constructor (opts = {}) {
56 super({
57 handler: (percent, msg, ...details) => {
58 this.updateProgress(percent, msg, details)
59 }
60 })
61
62 this.opts = opts
63
64 if (this.state) { return }
65
66 const len = opts.name.length
67
68 if (len > maxLengthName) {
69 maxLengthName = len
70 }
71
72 compilations[opts.name] = {
73 name: opts.name,
74 progress: 0,
75 running: false
76 }
77 }
78
79 get state () {
80 return compilations[this.opts.name]
81 }
82
83 updateProgress (percent, msg, details) {
84 const
85 progress = Math.floor(percent * 100),
86 wasRunning = this.state.running,
87 running = progress < 100
88
89 Object.assign(this.state, {
90 progress,
91 msg: running && msg ? msg : '',
92 details,
93 running
94 })
95
96 if (!wasRunning && running) {
97 this.state.startTime = +new Date()
98
99 if (isMinimalTerminal) {
100 log(`Compiling ${this.state.name}...`)
101 }
102 }
103 else if (wasRunning && !running) {
104 const diff = +new Date() - this.state.startTime
105 this.state.doneStamp = `in ~${ms(diff)}`
106
107 if (isMinimalTerminal) {
108 log(`Compiled ${this.state.name} ${this.state.doneStamp}`)
109 }
110 }
111
112 if (!isMinimalTerminal) {
113 if (running && isRunningGlobally()) {
114 render()
115 }
116 else {
117 render.cancel()
118 printState()
119 logLine.done()
120 }
121 }
122 }
123}