You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
3.6 KiB
139 lines
3.6 KiB
let chalk = require('chalk') |
|
let ProgressPlugin = require('webpack/lib/ProgressPlugin') |
|
let log = require('log-update') |
|
let path = require('path') |
|
|
|
const thresholder = 0.99 |
|
|
|
function now() { |
|
return new Date().toTimeString().split(' ')[0] |
|
} |
|
|
|
function isEqual(arr1, arr2) { |
|
let equal = arr1.length === arr2.length |
|
for (let i = 0; i < arr1.length; i++) { |
|
if (arr1[i] !== arr2[i]) { |
|
equal = false |
|
break |
|
} |
|
} |
|
return equal |
|
} |
|
|
|
class Progress { |
|
constructor(options) { |
|
this.delegate = new ProgressPlugin(options) |
|
} |
|
apply(compiler) { |
|
this.delegate.apply(compiler) |
|
let invalid = () => { |
|
console.log(chalk.white('Compiling...')) |
|
} |
|
if (compiler.hooks) { |
|
compiler.hooks.invalid.tap('ProgressWebpckPlugin', invalid) |
|
} else { |
|
compiler.plugin('invalid', invalid) |
|
} |
|
} |
|
} |
|
|
|
function progressPlugin(options = {}) { |
|
let identifier = options.identifier || '' |
|
let id = identifier && identifier + ' ' |
|
let onStart = options.onStart || (() => {}) |
|
let onFinish = options.onFinish |
|
let onProgress = options.onProgress |
|
let coloring = onProgress === undefined |
|
let clear = typeof options.clear === 'boolean' ? options.clear : true |
|
let startTime |
|
let finishTime |
|
let duration |
|
|
|
let prev = {} |
|
const handler = (percentage, message, ...args) => { |
|
startTime = Date.now() |
|
let output = [] |
|
if (percentage > thresholder) { |
|
return |
|
} |
|
if (percentage === 0) onStart() |
|
if (percentage > 0 && percentage < thresholder) { |
|
if (message === '') return |
|
if ( |
|
prev.percentage === percentage && |
|
prev.message === message && |
|
isEqual(prev.args, args) |
|
) { |
|
return |
|
} |
|
prev = { percentage, message, args } |
|
const banner = `[${Math.round(percentage * 100)}%] ` |
|
output.push(coloring ? chalk.yellow(banner) : banner) |
|
output.push( |
|
coloring ? chalk.white(`${message} ${id}`) : `${message} ${id}` |
|
) |
|
if (args.length > 0) { |
|
let details = args.join(' ') |
|
if ( |
|
/^\d+\/\d+\s{1}modules/.test(args[0]) === true && |
|
args.length === 2 |
|
) { |
|
const rootPath = path.resolve('.') |
|
details = [args[0]].concat([args[1].replace(rootPath, '')]).join(' ') |
|
} |
|
if (/^import\s{1}loader/.test(args[0]) === true && args.length === 1) { |
|
const matches = args[0].match( |
|
/^import\s{1}loader\s{1}(.+\/node_modules\/)/ |
|
) |
|
if (matches) { |
|
details = args[0].replace(matches[1], '') |
|
} |
|
} |
|
output.push(coloring ? chalk.grey(`(${details})`) : `(${details})`) |
|
} |
|
} |
|
|
|
// // 5. finished |
|
if (percentage === thresholder) { |
|
finishTime = Date.now() |
|
duration = (finishTime - startTime) / 1000 |
|
duration = duration.toFixed(3) |
|
|
|
if (typeof onFinish === 'function') { |
|
onFinish(id, now(), duration) |
|
} else { |
|
output.push( |
|
coloring |
|
? chalk.white(`Build ${id}finished at ${now()} by ${duration}s`) |
|
: `Build ${id}finished at ${now()} by ${duration}s` |
|
) |
|
} |
|
} |
|
if (onProgress) { |
|
if (percentage > 0 && percentage < thresholder) { |
|
onProgress(output, percentage) |
|
} |
|
} else { |
|
log(output.join('')) |
|
if (percentage === thresholder) { |
|
if (clear) { |
|
log.clear() |
|
} else { |
|
log.done() |
|
} |
|
} |
|
} |
|
} |
|
return new Progress({ |
|
handler, |
|
entries: false, |
|
activeModules: false, |
|
modules: true, |
|
modulesCount: 5000, |
|
dependencies: false, |
|
dependenciesCount: 10000, |
|
percentBy: 'entries' |
|
}) |
|
} |
|
|
|
module.exports = progressPlugin
|
|
|