text: /**
   * @fileoverview start webpack-dev-server 
   */
  
  'use strict'
  
  const chalk = require('chalk')
  const electron = require('electron')
  const path = require('path')
  const { say } = require('cfonts')
  const { spawn } = require('child_process')
  const webpack = require('webpack')
  const WebpackDevServer = require('webpack-dev-server')
  const webpackHotMiddleware = require('webpack-hot-middleware')
  
  const mainConfig = require('./webpack.main.config')
  const rendererConfig = require('./webpack.renderer.config')
  
  let electronProcess = null
  let manualRestart = false
  let hotMiddleware
  
  function logStats (proc, data) {
    let log = ''
  
    log += chalk.yellow.bold(`┏ ${proc} Process ${new Array((19 - proc.length) + 1).join('-')}`)
    log += '\n\n'
  
    if (typeof data === 'object') {
      data.toString({
        colors: true,
        chunks: false
      }).split(/\r?\n/).forEach(line => {
        log += '  ' + line + '\n'
      })
    } else {
      log += `  ${data}\n`
    }
  
    log += '\n' + chalk.yellow.bold(`┗ ${new Array(28 + 1).join('-')}`) + '\n'
  
    console.log(log)
  }
  
  /**
   * start webpack dev server and add hot reload support.
   * This function do the same thing as "webpack-dev-server" cli, 
   * which means you can access it through browser.
   */
  function startRenderer () {
    return new Promise((resolve, reject) => {
      rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client-hot-reload')].concat(rendererConfig.entry.renderer)
      console.log(rendererConfig.entry.renderer)
  
      const compiler = webpack(rendererConfig)
      hotMiddleware = webpackHotMiddleware(compiler, { 
        log: false, 
        heartbeat: 2500 
      })
  
      compiler.plugin('compilation', compilation => {
        compilation.plugin('html-webpack-plugin-after-emit', (data, cb) => {
          hotMiddleware.publish({ action: 'reload' })
          cb()
        })
      })
  
      compiler.plugin('done', stats => {
        logStats('Renderer', stats)
      })
  
      console.log(path.join(__dirname, '../'))
      const server = new WebpackDevServer(
        compiler,
        {
          contentBase: path.join(__dirname, '../'),
          quiet: true,
          setup (app, ctx) {
            app.use(hotMiddleware)
            ctx.middleware.waitUntilValid(() => {
              resolve()
            })
          }
        }
      )
  
      server.listen(9080)
    })
  }
  
  /**
   * start main process of electron
   */
  function startMain () {
    return new Promise((resolve, reject) => {
      mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
  
      const compiler = webpack(mainConfig)
  
      compiler.plugin('watch-run', (compilation, done) => {
        logStats('Main', chalk.white.bold('compiling...'))
        hotMiddleware.publish({ action: 'compiling' })
        done()
      })
  
      compiler.watch({}, (err, stats) => {
        if (err) {
          console.log(err)
          return
        }
  
        logStats('Main', stats)
  
        if (electronProcess && electronProcess.kill) {
          manualRestart = true
          process.kill(electronProcess.pid)
          electronProcess = null
          startElectron()
  
          setTimeout(() => {
            manualRestart = false
          }, 5000)
        }
  
        resolve()
      })
    })
  }
  
  /**
   * Start electron
   */
  function startElectron () {
    electronProcess = spawn(electron, ['--inspect=5858', path.join(__dirname, '../dist/electron/main.js')])
  
    electronProcess.stdout.on('data', data => {
      electronLog(data, 'blue')
    })
    electronProcess.stderr.on('data', data => {
      electronLog(data, 'red')
    })
  
    electronProcess.on('close', () => {
      if (!manualRestart) process.exit()
    })
  }
  
  /**
   * 
   * @param {*} data 
   * @param {*} color 
   */
  function electronLog (data, color) {
    let log = ''
    data = data.toString().split(/\r?\n/)
    data.forEach(line => {
      log += `  ${line}\n`
    })
    if (/[0-9A-z]+/.test(log)) {
      console.log(
        chalk[color].bold('┏ Electron -------------------') +
        '\n\n' +
        log +
        chalk[color].bold('┗ ----------------------------') +
        '\n'
      )
    }
  }
  
  /**
   * Print greeting message
   */
  function greeting () {
    const cols = process.stdout.columns
    let text = ''
  
    if (cols > 104) text = 'electron-vue'
    else if (cols > 76) text = 'electron-|vue'
    else text = false
  
    if (text) {
      say(text, {
        colors: ['yellow'],
        font: 'simple3d',
        space: false
      })
    } else console.log(chalk.yellow.bold('\n  electron-vue'))
    console.log(chalk.blue('  getting ready...') + '\n')
  }
  
  /**
   * init
   */
  function init () {
    greeting()
  
    Promise.all([startRenderer(), startMain()])
      .then(() => {
        startElectron()
      })
      .catch(err => {
        console.error(err)
      })
  }
  
  init()
  