import chalk from "chalk"; import webpack, {Plugin } from "webpack"; import ora from "ora"; import ProgressBar from "./ProgressBar"; const default_pattern = chalk.bold('[')+':percent:%'+chalk.bold('] ')+chalk.cyan.bold(':text:'); export interface Options { stream?: NodeJS.WriteStream; pattern?: string; pattern_no_stderr?: string; update_render?: boolean; clear?: boolean; clear_on_update?: boolean; stderr_check?: boolean; text?: string; } function ProgressOraPlugin(options:Options = {}) { options.pattern = options.pattern || default_pattern options.pattern_no_stderr = options.pattern_no_stderr || chalk.bold('█'); options.update_render = options.update_render || false; options.clear = options.clear || false; options.clear_on_update = options.clear_on_update || false; const pb = new ProgressBar('Generate...', 20, options.pattern_no_stderr); let stderr_check = false; let stream = options.stream || process.stderr; let enabled = stream && stream.isTTY; if (!enabled) { if (!options.stderr_check) { return function () {}; } stderr_check = true; } if(options.clear && !stderr_check) { stream.write('\x1Bc'); } else { stream.write('\n'); } options.text = options.pattern.replace(/\:percent\:/, '0').replace(/\:text\:/, 'build start'); let spinner = !stderr_check ? ora(options).start() : null; let isRunning = false; let startTime = 0; return new webpack.ProgressPlugin(function (percent:number, msg:string) { let newPercent = Math.ceil(percent * 100); if (!stderr_check) { if(options.clear_on_update) { stream.write('\x1Bc'); } if(spinner && options.pattern) spinner.text = options.pattern.replace(/\:percent\:/, newPercent.toString()).replace(/\:text\:/, msg) if(spinner && options.update_render) { spinner.render(); } } else { pb.render({ percent: (newPercent / 100).toFixed(4), completed: newPercent, total: 100, }) } if (!isRunning) { isRunning = true; startTime = (new Date()).getTime(); } else if (percent >= 1) { let now = (new Date()).getTime(); let buildTime = (now - startTime) / 1000 + 's'; if(stderr_check) { stream.write('\n' +chalk.green('✓') + chalk.green.bold(' Build completed in ' + buildTime + '\n\n')); } else { if(spinner) spinner.stop(); if(options.clear) { stream.write('\x1Bc'); } if(spinner) spinner.succeed(chalk.green.bold('Build completed in ' + buildTime + '\n\n')) } isRunning = false; } }); }; class WebpackProgressOraPlugin { constructor(options:Options = {}) { return ProgressOraPlugin(options) } apply(compiler: webpack.Compiler) {} } export default ProgressOraPlugin export { ProgressOraPlugin, WebpackProgressOraPlugin }