Skip to content

Commit

Permalink
feat: v2 rewrite
Browse files Browse the repository at this point in the history
BREAKING CHANGE: behaviour and options changed. Refer to the new docs
  • Loading branch information
Pooya Parsa committed Mar 31, 2018
1 parent 6bd92eb commit 5151960
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 152 deletions.
31 changes: 11 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@

<div align="center">
<br>
<img src="./assets/screen1.jpg" width="600px">
<img src="./assets/screen1.png" width="600px">
<p>Multi progress bars</p>
<br>
</div>

<div align="center">
<br>
<img src="./assets/screen2.jpg" width="90%">
<img src="./assets/screen2.png" width="600px">
<p>Build Profiler</p>
<br>
</div>
Expand Down Expand Up @@ -79,13 +79,6 @@ module.exports = {

<h2 align="center">Options</h2>

### `enabled`

By default only enabled when TTY is available and
not running in a [CI](https://github.com/watson/is-ci) environment.

You can force override this option by setting it to `true` or `false`.

### `name`
- Default: `webpack`

Expand All @@ -94,36 +87,34 @@ Display name
### `color`
- Default: `green`

Display color (can be hex (`#xxyyzz`) or a web color like `green`)
Display color (can be HEX like `#xxyyzz` or a web color like `green`).

### `profile`
- Default: `false`

Enable profiler
Enable profiler.

### `stream`
- Default: `process.stdout`
- Default: `process.stderr`

Output stream.

### `showCursor`
- Default: `false`

Show the cursor. This can be useful when a CLI accepts input from a user.
### `minimal`
- Default: Auto enabled on CI, non-TTY and test environments

Hide progress bar and only show Compiling/Compiled messages.

### `clear`
### `compiledIn`
- Default: `true`

Auto clear console when compile is finished.
Show `Compiled in ` message after build.

### `done`
- Type: `Function(sharedState, ctx)`

A function that will be called when **all** builds are finished.

### `buildTitle`
- Default: `BUILDING`

<h2 align="center">Maintainers</h2>

<table>
Expand Down
Binary file removed assets/screen1.jpg
Binary file not shown.
Binary file added assets/screen1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/screen2.jpg
Binary file not shown.
Binary file added assets/screen2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 2 additions & 4 deletions kitchen-sync/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ module.exports = {
},
plugins: [
new Self({
color: 'yellow',
showCursor: true,
color: 'orange',
profile: true,
clear: !true,
name: 'webpack-bar',
buildTitle: 'Wait',
logStateChanges: true,
}),
],
};
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@
"dependencies": {
"chalk": "^2.3.2",
"figures": "^2.0.0",
"is-ci": "^1.1.0",
"loader-utils": "^1.1.0",
"lodash": "^4.17.5",
"log-update": "^2.3.0",
"pretty-time": "^1.0.0",
"schema-utils": "^0.4.5",
"std-env": "^1.0.0",
"table": "^4.0.3"
},
"devDependencies": {
Expand All @@ -59,20 +59,20 @@
"del-cli": "^1.1.0",
"eslint": "^4.19.1",
"eslint-config-webpack": "^1.2.5",
"eslint-plugin-import": "^2.9.0",
"eslint-plugin-import": "^2.10.0",
"eslint-plugin-prettier": "^2.6.0",
"esm": "^3.0.11",
"esm": "^3.0.14",
"husky": "^0.14.3",
"jest": "^22.4.3",
"lint-staged": "^7.0.0",
"lint-staged": "^7.0.1",
"memory-fs": "^0.4.1",
"nsp": "^3.2.1",
"pre-commit": "^1.2.2",
"prettier": "^1.11.1",
"standard-version": "^4.3.0",
"webpack": "^4.3.0",
"webpack": "^4.4.1",
"webpack-cli": "^2.0.13",
"webpack-defaults": "^2.0.0"
"webpack-defaults": "^2.1.1"
},
"engines": {
"node": ">= 6.9.0 || >= 8.9.0"
Expand Down
177 changes: 81 additions & 96 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import webpack from 'webpack';
import chalk from 'chalk';
import _ from 'lodash';
import logUpdate from 'log-update';
import isCI from 'is-ci';
import env from 'std-env';
import prettyTime from 'pretty-time';
import Profile from './profile';
import {
BULLET,
TICK,
parseRequst,
formatRequest,
renderBar,
Expand All @@ -18,74 +20,45 @@ const sharedState = {};
const defaults = {
name: 'webpack',
color: 'green',
stream: process.stdout,
profile: false,
clear: true,
showCursor: false,
enabled: process.stdout.isTTY && !isCI,
compiledIn: true,
done: null,
buildTitle: 'BUILDING',
minimal: env.minimalCLI,
stream: process.stderr,
};

const hasRunning = () => Object.values(sharedState).find((s) => s.isRunning);

export default class WebpackBarPlugin extends webpack.ProgressPlugin {
constructor(options) {
super();

this.options = Object.assign({}, defaults, options);

if (!this.options.enabled) {
return;
}

// this.handler will be called by webpack.ProgressPlugin
this.handler = (percent, msg, ...details) =>
this.updateProgress(percent, msg, details);

this._render = _.throttle(this.render, 25);

this.logUpdate =
this.options.logUpdate ||
logUpdate.create(this.options.stream, {
showCursor: this.options.showCursor,
});
this.logUpdate = this.options.logUpdate || logUpdate;

if (!sharedState[this.options.name]) {
if (!this.state) {
sharedState[this.options.name] = {
isRunning: false,
color: this.options.color,
profile: this.options.profile ? new Profile(this.options.name) : null,
};
}
}

apply(compiler) {
if (!this.options.enabled) {
return;
}

super.apply(compiler);

if (compiler.hooks) {
// Webpack >= 4
compiler.hooks.done.tap('webpackbar', () => this.done());
} else {
// Webpack < 4
compiler.plugin('done', () => this.done());
}
get state() {
return sharedState[this.options.name];
}

done() {
if (!this.options.enabled) {
return;
}

if (Object.values(sharedState).find((s) => s.isRunning)) {
return;
}

this.render();

if (this.options.profile) {
const stats = sharedState[this.options.name].profile.getStats();
const stats = this.state.profile.getStats();
printStats(stats);
}

Expand All @@ -95,80 +68,92 @@ export default class WebpackBarPlugin extends webpack.ProgressPlugin {
}

updateProgress(percent, msg, details) {
if (!this.options.enabled) {
return;
}

const progress = Math.floor(percent * 100);
const isRunning = progress && progress !== 100;
const isRunning = progress < 100;

Object.assign(sharedState[this.options.name], {
const wasRunning = this.state.isRunning;

Object.assign(this.state, {
progress,
msg: isRunning ? msg || '' : 'done',
msg: isRunning && msg ? msg : '',
details: details || [],
request: parseRequst(details[2]),
isRunning,
});

if (!wasRunning && isRunning) {
// Started
this.state.start = process.hrtime();
if (this.options.minimal) {
this.stream.write(`Compiling ${this.options.name}\n`);
}
delete this.state.time;
} else if (wasRunning && !isRunning) {
// Finished
const time = process.hrtime(this.state.start);
if (this.options.minimal) {
this.stream.write(
`Compiled ${this.options.name} in ${prettyTime(this.state.time)}\n`
);
} else {
this.logUpdate.clear();
if (this.options.compiledIn) {
process.stdout.write(
`${[
TICK,
this.options.name,
'compiled in',
prettyTime(time, 'ms'),
].join(' ')}\n`
);
}
}
delete this.state.start;
}

if (this.options.profile) {
sharedState[this.options.name].profile.onRequest(
sharedState[this.options.name].request
);
this.state.profile.onRequest(this.state.request);
}

this._render();
if (hasRunning()) {
this._render();
} else {
this.logUpdate.clear();
this.done();
}
}

render() {
const shouldClear = this.options.clear;
let someRunning = false;

const lines = [];

_.sortBy(Object.keys(sharedState), (s) => s.name)
.reverse()
.forEach((name) => {
const state = sharedState[name];

if (state.isRunning) {
someRunning = true;
} else if (shouldClear) {
// Skip done jobs
return;
}

const lColor = colorize(state.color);
const lIcon = lColor(BULLET);
const lName = lColor(_.startCase(name));
const lBar = renderBar(state.progress, state.color);
const lMsg = _.startCase(state.msg);
const lProgress = `(${state.progress || 0}%)`;
const lDetail1 = chalk.grey((state.details && state.details[0]) || '');
const lDetail2 = chalk.grey((state.details && state.details[1]) || '');
const lRequest = state.request ? formatRequest(state.request) : '';

lines.push(
`${[lIcon, lName, lBar, lMsg, lProgress, lDetail1, lDetail2].join(
' '
)}\n ${lRequest}`
);
});

if (shouldClear && !someRunning) {
this.logUpdate.clear();
if (this.options.minimal) {
return;
}

const lLines = lines.join('\n\n');
const stateLines = _.sortBy(Object.keys(sharedState), (n) => n)
.filter((s) => sharedState[s].isRunning || sharedState[s].start)
.map((name) => {
const state = sharedState[name];
const color = colorize(state.color);

if (this.options.buildTitle) {
const title = someRunning
? ` ${chalk.bgBlue.black(` ${this.options.buildTitle} `)}`
: '';
if (!state.isRunning) {
return `${[chalk.grey(BULLET), name].join(' ')}`;
}

this.logUpdate(`\n${title}\n\n${lLines}`);
} else {
this.logUpdate(`\n${lLines}`);
return `${[
color(BULLET),
color(name),
renderBar(state.progress, state.color),
state.msg,
`(${state.progress || 0}%)`,
chalk.grey((state.details && state.details[0]) || ''),
chalk.grey((state.details && state.details[1]) || ''),
].join(' ')}\n ${state.request ? formatRequest(state.request) : ''}\n`;
})
.filter(Boolean);

if (stateLines.length) {
const title = chalk.underline.blue('Compiling');
const log = `\n${title}\n\n${stateLines.join('\n')}`;
this.logUpdate(log);
}
}
}
Loading

0 comments on commit 5151960

Please sign in to comment.