1 | 'use strict'
|
2 |
|
3 | const WebpackProgressPlugin = require('webpack/lib/ProgressPlugin')
|
4 | const { ProgressBar } = require('@mara/devkit')
|
5 | const readline = require('readline')
|
6 |
|
7 | class ProcessDetails {
|
8 | constructor({ stdout = process.stderr, spinner, name }) {
|
9 | this.stdout = stdout
|
10 | this.spinner = spinner
|
11 | this.name = name ? `${name}:` : ''
|
12 | }
|
13 |
|
14 | _clearLine() {
|
15 | readline.clearLine(this.stdout, 0)
|
16 | readline.cursorTo(this.stdout, 0)
|
17 | }
|
18 |
|
19 | update(percent, msg, details) {
|
20 | if (percent < 1) {
|
21 | percent = Math.floor(percent * 100)
|
22 | msg = `${percent}% ${msg}`
|
23 |
|
24 | if (percent < 100) {
|
25 | msg = ` ${msg}`
|
26 | }
|
27 | if (percent < 10) {
|
28 | msg = ` ${msg}`
|
29 | }
|
30 |
|
31 | for (let detail of details) {
|
32 | if (!detail) continue
|
33 |
|
34 | if (detail.length > 40) {
|
35 | detail = '...'
|
36 | }
|
37 | msg += ` ${detail}`
|
38 | }
|
39 | }
|
40 |
|
41 | msg = this.name + msg
|
42 |
|
43 | if (this.spinner) {
|
44 | this.spinner.text = msg
|
45 | return
|
46 | }
|
47 |
|
48 | readline.cursorTo(this.stdout, 0)
|
49 | this.stdout.write(msg)
|
50 | }
|
51 |
|
52 | stop() {
|
53 | this._clearLine(this.stdout)
|
54 | }
|
55 | }
|
56 |
|
57 | module.exports = class BuildProgressPlugin {
|
58 | constructor(options) {
|
59 | const defOpt = {
|
60 | name: '',
|
61 | spinner: null,
|
62 | type: '',
|
63 | stdout: process.stderr
|
64 | }
|
65 |
|
66 | this.options = Object.assign(defOpt, options)
|
67 |
|
68 | const stdout = this.options.stdout
|
69 | const spinner = this.options.spinner
|
70 |
|
71 |
|
72 | if (!stdout.isTTY) return () => {}
|
73 |
|
74 | this.progressPlugin = new WebpackProgressPlugin(
|
75 | this.buildProgress.bind(this)
|
76 | )
|
77 |
|
78 | const ProcessRender =
|
79 | this.options.type === 'text' ? ProcessDetails : ProgressBar
|
80 | this.progressBar = new ProcessRender({
|
81 | spinner,
|
82 | stdout,
|
83 | name: this.options.name
|
84 | })
|
85 | }
|
86 |
|
87 | apply(compiler) {
|
88 | this.progressPlugin.apply(compiler)
|
89 | }
|
90 |
|
91 | buildProgress(percent, msg, ...args) {
|
92 | const details = args
|
93 |
|
94 | if (percent === 1) {
|
95 | return this.progressBar.stop()
|
96 | }
|
97 |
|
98 | this.progressBar.update(percent, msg, details)
|
99 | }
|
100 | }
|