| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 | // From https://github.com/FormidableLabs/webpack-dashboard/blob/7f99b31c5f00a7818d8129cb8a8fc6eb1b71799c/plugin/index.js// Modified by Guillaume Chau (Akryum)/* eslint-disable max-params, max-statements */'use strict'const path = require('path')const fs = require('fs-extra')const webpack = require('webpack')const { IpcMessenger } = require('@vue/cli-shared-utils')const { analyzeBundle } = require('./analyzeBundle')const ID = 'vue-cli-dashboard-plugin'const ONE_SECOND = 1000const FILENAME_QUERY_REGEXP = /\?.*$/const ipc = new IpcMessenger()function getTimeMessage (timer) {  let time = Date.now() - timer  if (time >= ONE_SECOND) {    time /= ONE_SECOND    time = Math.round(time)    time += 's'  } else {    time += 'ms'  }  return ` (${time})`}class DashboardPlugin {  constructor (options) {    this.type = options.type    if (this.type === 'build' && options.modernBuild) {      this.type = 'build-modern'    }    this.watching = false    this.autoDisconnect = !options.keepAlive  }  cleanup () {    this.sendData = null    if (this.autoDisconnect) ipc.disconnect()  }  apply (compiler) {    let sendData = this.sendData    let timer    let assetSources = new Map()    if (!sendData) {      sendData = data => ipc.send({        webpackDashboardData: {          type: this.type,          value: data        }      })    }    // Progress status    let progressTime = Date.now()    const progressPlugin = new webpack.ProgressPlugin((percent, msg) => {      // Debouncing      const time = Date.now()      if (time - progressTime > 300) {        progressTime = time        sendData([          {            type: 'status',            value: 'Compiling'          },          {            type: 'progress',            value: percent          },          {            type: 'operations',            value: msg + getTimeMessage(timer)          }        ])      }    })    progressPlugin.apply(compiler)    compiler.hooks.watchRun.tap(ID, c => {      this.watching = true    })    compiler.hooks.run.tap(ID, c => {      this.watching = false    })    compiler.hooks.compile.tap(ID, () => {      timer = Date.now()      sendData([        {          type: 'status',          value: 'Compiling'        },        {          type: 'progress',          value: 0        }      ])    })    compiler.hooks.invalid.tap(ID, () => {      sendData([        {          type: 'status',          value: 'Invalidated'        },        {          type: 'progress',          value: 0        },        {          type: 'operations',          value: 'idle'        }      ])    })    compiler.hooks.failed.tap(ID, () => {      sendData([        {          type: 'status',          value: 'Failed'        },        {          type: 'operations',          value: `idle${getTimeMessage(timer)}`        }      ])    })    compiler.hooks.afterEmit.tap(ID, compilation => {      assetSources = new Map()      for (const name in compilation.assets) {        const asset = compilation.assets[name]        assetSources.set(name.replace(FILENAME_QUERY_REGEXP, ''), asset.source())      }    })    compiler.hooks.done.tap(ID, stats => {      let statsData = stats.toJson()      // Sometimes all the information is located in `children` array      if ((!statsData.assets || !statsData.assets.length) && statsData.children && statsData.children.length) {        statsData = statsData.children[0]      }      const outputPath = compiler.options.output.path      statsData.assets.forEach(asset => {        // Removing query part from filename (yes, somebody uses it for some reason and Webpack supports it)        asset.name = asset.name.replace(FILENAME_QUERY_REGEXP, '')        asset.fullPath = path.join(outputPath, asset.name)      })      // Analyze the assets and update sizes on assets and modules      analyzeBundle(statsData, assetSources)      const hasErrors = stats.hasErrors()      sendData([        {          type: 'status',          value: hasErrors ? 'Failed' : 'Success'        },        {          type: 'progress',          value: 1        },        {          type: 'operations',          value: `idle${getTimeMessage(timer)}`        }      ])      const statsFile = path.resolve(process.cwd(), `./node_modules/.stats-${this.type}.json`)      fs.writeJson(statsFile, {        errors: hasErrors,        warnings: stats.hasWarnings(),        data: statsData      }).then(() => {        sendData([          {            type: 'stats'          }        ])        if (!this.watching) {          this.cleanup()        }      }).catch(error => {        console.error(error)      })    })  }}module.exports = DashboardPlugin
 |