1 | const capitalize = require('titleize');
|
2 | const chalk = require('chalk');
|
3 | const ora = require('ora');
|
4 |
|
5 | const parse = require('./parse');
|
6 | const Reporter = require('./Reporter');
|
7 |
|
8 | const style = require('./stylish/style');
|
9 |
|
10 | module.exports = class StylishReporter extends Reporter {
|
11 | constructor(options) {
|
12 | super(options);
|
13 |
|
14 | this.rendered = {
|
15 | footer: false,
|
16 | header: false
|
17 | };
|
18 |
|
19 | this.spinner = ora();
|
20 |
|
21 | this.state = {
|
22 | active: 0,
|
23 | hashes: [],
|
24 | instances: 0,
|
25 | totals: {
|
26 | errors: 0,
|
27 | time: 0,
|
28 | warnings: 0
|
29 | },
|
30 | time: 0
|
31 | };
|
32 | }
|
33 |
|
34 |
|
35 |
|
36 | progress(stage) {
|
37 | if (!this.spinner.isSpinning && stage.step.percentage < 1) {
|
38 | this.spinner.start(stage.step.name);
|
39 | }
|
40 |
|
41 | const name = capitalize(stage.step.name);
|
42 | const percent = Math.floor(stage.step.percentage * 100);
|
43 |
|
44 | this.spinner.text = chalk`${name} {dim (${percent}%)}`;
|
45 |
|
46 | if (stage.step.percentage >= 1) {
|
47 | this.spinner.stop();
|
48 | }
|
49 | }
|
50 |
|
51 | render(error, resultStats) {
|
52 | if (error) {
|
53 | return error;
|
54 | }
|
55 |
|
56 |
|
57 | const allStats = resultStats.stats || [resultStats];
|
58 | const compilers = this.compiler.compilers || [this.compiler];
|
59 | const { compiler, state, rendered } = this;
|
60 | const { log } = console;
|
61 | const opts = {
|
62 | context: compiler.context,
|
63 | cached: false,
|
64 | cachedAssets: false,
|
65 | exclude: ['node_modules', 'bower_components', 'components']
|
66 | };
|
67 | const out = [];
|
68 | const first = allStats[0].toJson(opts, true);
|
69 | const { version } = first;
|
70 |
|
71 | out.push(chalk.cyan(`\nwebpack v${version}\n`));
|
72 |
|
73 | state.instances = allStats.length;
|
74 |
|
75 | for (const stats of allStats) {
|
76 | const json = stats.toJson(opts, true);
|
77 |
|
78 |
|
79 |
|
80 | if (state.hashes.includes(json.hash)) {
|
81 | return null;
|
82 | }
|
83 |
|
84 | state.hashes.push(json.hash);
|
85 | state.time += json.time;
|
86 |
|
87 |
|
88 | const compilerIndex = allStats.indexOf(stats);
|
89 | const compilerOptions = compilers[compilerIndex].options;
|
90 | const problems = style.problems(parse.problems(json, state));
|
91 | const files = style.files(parse.files(json), compilerOptions);
|
92 | const hidden = style.hidden(parse.hidden(json));
|
93 | const hash = style.hash(json, files, hidden);
|
94 |
|
95 | out.push(hash);
|
96 | out.push(problems);
|
97 | }
|
98 |
|
99 | const footer = style.footer(parse.footer(state));
|
100 |
|
101 | if (footer.length) {
|
102 | rendered.footer = true;
|
103 | out.push(footer);
|
104 | }
|
105 |
|
106 | state.totals = { errors: 0, time: 0, warnings: 0 };
|
107 |
|
108 | const result = out.join('\n');
|
109 |
|
110 | log(result);
|
111 |
|
112 | if (rendered.footer && compilers.some((comp) => comp.options.watch === true)) {
|
113 | log();
|
114 | }
|
115 |
|
116 |
|
117 | return result;
|
118 | }
|
119 | };
|