1 | const path = require('path')
|
2 | const chalk = require('chalk')
|
3 | const textTable = require('text-table')
|
4 | const gzipSize = require('gzip-size')
|
5 | const formatWebpackMessages = require('@poi/dev-utils/formatWebpackMessages')
|
6 | const prettyBytes = require('@poi/dev-utils/prettyBytes')
|
7 | const logger = require('@poi/logger')
|
8 | const prettyTime = require('pretty-ms')
|
9 |
|
10 | class PrintStatusPlugin {
|
11 | constructor(opts = {}) {
|
12 | this.opts = opts
|
13 | }
|
14 |
|
15 | apply(compiler) {
|
16 | compiler.hooks.invalid.tap('show-rebuild-reason', file => {
|
17 | const d = new Date()
|
18 | logger.log(
|
19 | chalk.dim(
|
20 | `[${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}] Rebuilding due to changes in ${file}`
|
21 | )
|
22 | )
|
23 | })
|
24 |
|
25 | compiler.hooks.done.tapPromise('print-status', async stats => {
|
26 | if (this.opts.clearConsole !== false && process.env.NODE_ENV !== 'test') {
|
27 | require('@poi/dev-utils/clearConsole')()
|
28 | }
|
29 | if (stats.hasErrors() || stats.hasWarnings()) {
|
30 | if (stats.hasErrors()) {
|
31 | process.exitCode = 1
|
32 | }
|
33 |
|
34 |
|
35 | const messages = formatWebpackMessages(stats.toJson())
|
36 | if (messages) {
|
37 | const { errors, warnings } = messages
|
38 | for (const error of errors) {
|
39 | console.error(error)
|
40 | }
|
41 | for (const warning of warnings) {
|
42 | console.error(warning)
|
43 | }
|
44 | }
|
45 |
|
46 | logger.debug(() =>
|
47 | stats.toString({
|
48 | colors: true
|
49 | })
|
50 | )
|
51 | } else {
|
52 | if (this.opts.printSucessMessage) {
|
53 | logger.done(
|
54 | `Build completed in ${prettyTime(stats.endTime - stats.startTime)}`
|
55 | )
|
56 | }
|
57 |
|
58 | if (
|
59 | (this.opts.printFileStats || logger.options.debug) &&
|
60 | !process.env.CI &&
|
61 | process.stdout.isTTY
|
62 | ) {
|
63 | logger.log()
|
64 | const assets = await Promise.all(
|
65 | stats.toJson().assets.map(async asset => {
|
66 | asset.gzipped = await gzipSize(
|
67 | stats.compilation.assets[asset.name].source()
|
68 | )
|
69 | return asset
|
70 | })
|
71 | )
|
72 | const data = assets.map(asset => {
|
73 | const filename = path.relative(
|
74 | process.cwd(),
|
75 | path.join(compiler.options.output.path, asset.name)
|
76 | )
|
77 | return [
|
78 | path.join(
|
79 | path.dirname(filename),
|
80 | chalk.bold(path.basename(filename))
|
81 | ),
|
82 | chalk.green(prettyBytes(asset.size)),
|
83 | chalk.green(prettyBytes(asset.gzipped))
|
84 | ]
|
85 | })
|
86 | data.unshift([
|
87 | chalk.bold('file'),
|
88 | chalk.bold('size'),
|
89 | chalk.bold('gzipped')
|
90 | ])
|
91 | data.push([
|
92 | '(total)',
|
93 | chalk.green(
|
94 | prettyBytes(
|
95 | assets.reduce((result, asset) => result + asset.size, 0)
|
96 | )
|
97 | ),
|
98 | chalk.green(
|
99 | prettyBytes(
|
100 | assets.reduce((result, asset) => result + asset.gzipped, 0)
|
101 | )
|
102 | )
|
103 | ])
|
104 | logger.log(
|
105 | textTable(data, {
|
106 | stringLength: require('string-width')
|
107 | })
|
108 | )
|
109 | }
|
110 | }
|
111 | })
|
112 | }
|
113 | }
|
114 |
|
115 | module.exports = PrintStatusPlugin
|