webpackbar
webpackbar copied to clipboard
erase the prev lines length
problem description
- when the process.stderr.columns less than console.log('xxxxxx') string width, extra lines log, wrap line normal;
- the prevLineCount variable length calculate error;
- cause the terminal stdout occurs many whitespace lines;
source code
// LogUpdate -> render
const data = ansiEscapes.eraseLines(this.prevLineCount) + wrappedLines + '\n' + this.extraLines;
this.write(data);
// it's my problem === length is not true
this.prevLineCount = data.split('\n').length;
could you calculate length below?
this.prevLineCount = data.split('\n').length;
this.extraLines.split('\n').forEach(str => {
if (str.length > this.columns) {
this.prevLineCount += 1
}
});
That's all, thank you!
Hi @LIUeng. Nice find sure it would be nice idea doing wrap aware line-count. Do you mind opening a PR for fix?
Hi @LIUeng. Nice find sure it would be nice idea doing wrap aware line-count. Do you mind opening a PR for fix?
I'm sorry too late reply! Yes, I'am pleasure fix the problem!
I was just experiencing this bug where extra whitespace lines are added for each line update when showing progress. Looking forward to seeing this addressed. Thanks @LIUeng
Here is my patch if anyone is interested. generated using https://github.com/ds300/patch-package
basically, wrapped lines needs to be taken into account when counting the lines, to get the correct line length you need to strip the ascii-escapes.
This works, however it might slip up when resizing the window because prevLineCount may not be updated during resize and re-render will briefly have the wrong count, it might add or remove lines. it's a rare occurrence though and should be ok.
diff --git a/node_modules/webpackbar/dist/webpackbar.js b/node_modules/webpackbar/dist/webpackbar.js
index 2ece25a..7ff3aca 100644
--- a/node_modules/webpackbar/dist/webpackbar.js
+++ b/node_modules/webpackbar/dist/webpackbar.js
@@ -22,6 +22,23 @@ const textTable__default = /*#__PURE__*/_interopDefaultLegacy(textTable);
const ansiEscapes__default = /*#__PURE__*/_interopDefaultLegacy(ansiEscapes);
const wrapAnsi__default = /*#__PURE__*/_interopDefaultLegacy(wrapAnsi);
+function ansiRegex({onlyFirst = false} = {}) {
+ const pattern = [
+ '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
+ '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))'
+ ].join('|');
+
+ return new RegExp(pattern, onlyFirst ? undefined : 'g');
+}
+
+function stripAnsi(string) {
+ if (typeof string !== 'string') {
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
+ }
+
+ return string.replace(ansiRegex(), '');
+}
+
function first(arr) {
return arr[0];
}
@@ -136,7 +153,9 @@ class LogUpdate {
});
const data = ansiEscapes__default['default'].eraseLines(this.prevLineCount) + wrappedLines + "\n" + this.extraLines;
this.write(data);
- this.prevLineCount = data.split("\n").length;
+ this.prevLineCount = stripAnsi(data).split("\n")
+ .map(l => l.length == 0 ? 1 : Math.ceil(l.length / this.columns))
+ .reduce((a, b) => a+b);
}
get columns() {
return (process.stderr.columns || 80) - 2;
@@ -159,8 +178,12 @@ class LogUpdate {
this.extraLines = "";
}
_onData(data) {
- const str = String(data);
- const lines = str.split("\n").length - 1;
+ const str = stripAnsi(data);
+ const lines = str
+ .split("\n")
+ .map(l => l.length == 0 ? 1 : Math.ceil(l.length / this.columns))
+ .reduce((a, b) => a+b) - 1;
+
if (lines > 0) {
this.prevLineCount += lines;
this.extraLines += data;
@@ -468,7 +491,10 @@ class WebpackBarPlugin extends webpack.ProgressPlugin {
super({activeModules: true});
this.options = Object.assign({}, DEFAULTS, options);
this.handler = (percent, message, ...details) => {
- this.updateProgress(percent, message, details);
+ // Webpack is initilizing the progress way too early
+ if (percent > 0.01){
+ this.updateProgress(percent, message, details);
+ }
};
const _reporters = Array.from(this.options.reporters || []).concat(this.options.reporter).filter(Boolean).map((reporter) => {
if (Array.isArray(reporter)) {