index.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. let chalk = require('chalk')
  2. let ProgressPlugin = require('webpack/lib/ProgressPlugin')
  3. let log = require('log-update')
  4. let path = require('path')
  5. const thresholder = 0.99
  6. function now() {
  7. return new Date().toTimeString().split(' ')[0]
  8. }
  9. function isEqual(arr1, arr2) {
  10. let equal = arr1.length === arr2.length
  11. for (let i = 0; i < arr1.length; i++) {
  12. if (arr1[i] !== arr2[i]) {
  13. equal = false
  14. break
  15. }
  16. }
  17. return equal
  18. }
  19. class Progress {
  20. constructor(options) {
  21. this.delegate = new ProgressPlugin(options)
  22. }
  23. apply(compiler) {
  24. this.delegate.apply(compiler)
  25. let invalid = () => {
  26. console.log(chalk.white('Compiling...'))
  27. }
  28. if (compiler.hooks) {
  29. compiler.hooks.invalid.tap('ProgressWebpckPlugin', invalid)
  30. } else {
  31. compiler.plugin('invalid', invalid)
  32. }
  33. }
  34. }
  35. function progressPlugin(options = {}) {
  36. let identifier = options.identifier || ''
  37. let id = identifier && identifier + ' '
  38. let onStart = options.onStart || (() => {})
  39. let onFinish = options.onFinish
  40. let onProgress = options.onProgress
  41. let coloring = onProgress === undefined
  42. let clear = typeof options.clear === 'boolean' ? options.clear : true
  43. let startTime
  44. let finishTime
  45. let duration
  46. let prev = {}
  47. const handler = (percentage, message, ...args) => {
  48. startTime = Date.now()
  49. let output = []
  50. if (percentage > thresholder) {
  51. return
  52. }
  53. if (percentage === 0) onStart()
  54. if (percentage > 0 && percentage < thresholder) {
  55. if (message === '') return
  56. if (
  57. prev.percentage === percentage &&
  58. prev.message === message &&
  59. isEqual(prev.args, args)
  60. ) {
  61. return
  62. }
  63. prev = { percentage, message, args }
  64. const banner = `[${Math.round(percentage * 100)}%] `
  65. output.push(coloring ? chalk.yellow(banner) : banner)
  66. output.push(
  67. coloring ? chalk.white(`${message} ${id}`) : `${message} ${id}`
  68. )
  69. if (args.length > 0) {
  70. let details = args.join(' ')
  71. if (
  72. /^\d+\/\d+\s{1}modules/.test(args[0]) === true &&
  73. args.length === 2
  74. ) {
  75. const rootPath = path.resolve('.')
  76. details = [args[0]].concat([args[1].replace(rootPath, '')]).join(' ')
  77. }
  78. if (/^import\s{1}loader/.test(args[0]) === true && args.length === 1) {
  79. const matches = args[0].match(
  80. /^import\s{1}loader\s{1}(.+\/node_modules\/)/
  81. )
  82. if (matches) {
  83. details = args[0].replace(matches[1], '')
  84. }
  85. }
  86. output.push(coloring ? chalk.grey(`(${details})`) : `(${details})`)
  87. }
  88. }
  89. // // 5. finished
  90. if (percentage === thresholder) {
  91. finishTime = Date.now()
  92. duration = (finishTime - startTime) / 1000
  93. duration = duration.toFixed(3)
  94. if (typeof onFinish === 'function') {
  95. onFinish(id, now(), duration)
  96. } else {
  97. output.push(
  98. coloring
  99. ? chalk.white(`Build ${id}finished at ${now()} by ${duration}s`)
  100. : `Build ${id}finished at ${now()} by ${duration}s`
  101. )
  102. }
  103. }
  104. if (onProgress) {
  105. if (percentage > 0 && percentage < thresholder) {
  106. onProgress(output, percentage)
  107. }
  108. } else {
  109. log(output.join(''))
  110. if (percentage === thresholder) {
  111. if (clear) {
  112. log.clear()
  113. } else {
  114. log.done()
  115. }
  116. }
  117. }
  118. }
  119. return new Progress({
  120. handler,
  121. entries: false,
  122. activeModules: false,
  123. modules: true,
  124. modulesCount: 5000,
  125. dependencies: false,
  126. dependenciesCount: 10000,
  127. percentBy: 'entries'
  128. })
  129. }
  130. module.exports = progressPlugin