Skip to content

Commit cdd5547

Browse files
committed
feat: add option to keep webpackbar on the bottom
1 parent 0f1cb60 commit cdd5547

File tree

4 files changed

+36
-13
lines changed

4 files changed

+36
-13
lines changed

src/plugin.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { startCase, shortenPath, objectValues } from "./utils";
44
import type { WebpackBarOptions, ReporterOpts, Reporter, State } from "./types";
55
import * as reporters from "./reporters";
66
import { parseRequest, hook } from "./utils/webpack";
7+
import { logUpdate } from "./utils/log-update";
78

89
export type { Reporter, State } from "./types";
910

@@ -29,12 +30,16 @@ const DEFAULT_STATE = () => ({
2930
const globalStates: { [key: string]: State } = {};
3031

3132
export class WebpackBar {
32-
private options: any;
33+
private options: WebpackBarOptions;
3334
private reporters: Reporter[];
3435

3536
constructor(options?: WebpackBarOptions) {
3637
this.options = Object.assign({}, DEFAULTS, options);
3738

39+
if (options.keepOnBottom) {
40+
logUpdate.keepOnBottom = true;
41+
}
42+
3843
// Reporters
3944
const _reporters: ReporterOpts[] = [
4045
...(this.options.reporters || []),

src/reporters/fancy.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ import { grey } from "ansis";
22
import { renderBar, colorize, ellipsisLeft } from "../utils/cli";
33
import { formatRequest } from "../utils/webpack";
44
import { BULLET, TICK, CROSS, CIRCLE_OPEN } from "../utils/consts";
5-
import LogUpdate from "../utils/log-update";
5+
import { logUpdate } from "../utils/log-update";
66
import { Reporter } from "../types";
77

8-
const logUpdate = new LogUpdate();
9-
108
let lastRender = Date.now();
119

1210
export default class FancyReporter implements Reporter {

src/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ export interface WebpackBarOptions {
8383
*/
8484
fancy?: boolean;
8585

86+
/**
87+
* Keep the bar at the bottom of the terminal until build is finished.
88+
* Messages logged during the build will appear above the bar.
89+
* Only applies when the fancy reporter is used.
90+
* @default false
91+
*/
92+
keepOnBottom?: boolean;
93+
8694
/**
8795
* Enable a simple log reporter (only start and end)
8896
* Defaults to 'true' when running in minimal environments

src/utils/log-update.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { eraseLines } from "./cli";
66

77
const originalWrite = Symbol("webpackbarWrite");
88

9-
export default class LogUpdate {
9+
class LogUpdate {
10+
public keepOnBottom = false;
1011
private prevLines: string | null;
1112
private listening: boolean;
1213
private extraLines: string;
@@ -29,11 +30,10 @@ export default class LogUpdate {
2930
wordWrap: false,
3031
});
3132

32-
const data =
33-
eraseLines(this.lineCount) + wrappedLines + "\n" + this.extraLines;
33+
const linesToWrite = wrappedLines + "\n" + this.extraLines;
34+
this.write(eraseLines(this.lineCount) + linesToWrite);
3435

35-
this.write(data);
36-
this.prevLines = data;
36+
this.prevLines = linesToWrite;
3737
}
3838

3939
/**
@@ -82,14 +82,22 @@ export default class LogUpdate {
8282
}
8383

8484
_onData(data) {
85-
const str = String(data);
86-
const lines = str.split("\n").length - 1;
87-
if (lines > 0) {
85+
if (this.keepOnBottom) {
86+
// Erase the progress bar so that the data can be printed above it
87+
this.write(eraseLines(this.lineCount));
88+
} else {
8889
this.prevLines += data;
8990
this.extraLines += data;
9091
}
9192
}
9293

94+
_afterData() {
95+
if (this.keepOnBottom) {
96+
// Re-draw the bar in the new position after the printed data
97+
this.write(this.prevLines);
98+
}
99+
}
100+
93101
listen() {
94102
// Prevent listening more than once
95103
if (this.listening) {
@@ -109,7 +117,9 @@ export default class LogUpdate {
109117
return stream.write(data, ...args);
110118
}
111119
this._onData(data);
112-
return stream.write[originalWrite].call(stream, data, ...args);
120+
const result = stream.write[originalWrite].call(stream, data, ...args);
121+
this._afterData();
122+
return result;
113123
};
114124

115125
// Backup original write fn
@@ -133,3 +143,5 @@ export default class LogUpdate {
133143
this.listening = false;
134144
}
135145
}
146+
147+
export const logUpdate = new LogUpdate();

0 commit comments

Comments
 (0)