dev-runner.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. 'use strict'
  2. const chalk = require('chalk')
  3. const electron = require('electron')
  4. const path = require('path')
  5. const { say } = require('cfonts')
  6. const { spawn } = require('child_process')
  7. const webpack = require('webpack')
  8. const WebpackDevServer = require('webpack-dev-server')
  9. const webpackHotMiddleware = require('webpack-hot-middleware')
  10. const mainConfig = require('./webpack.main.config')
  11. const rendererConfig = require('./webpack.renderer.config')
  12. let electronProcess = null
  13. let manualRestart = false
  14. let hotMiddleware
  15. function logStats (proc, data) {
  16. let log = ''
  17. log += chalk.yellow.bold(`┏ ${proc} Process ${new Array((19 - proc.length) + 1).join('-')}`)
  18. log += '\n\n'
  19. if (typeof data === 'object') {
  20. data.toString({
  21. colors: true,
  22. chunks: false
  23. }).split(/\r?\n/).forEach(line => {
  24. log += ' ' + line + '\n'
  25. })
  26. } else {
  27. log += ` ${data}\n`
  28. }
  29. log += '\n' + chalk.yellow.bold(`┗ ${new Array(28 + 1).join('-')}`) + '\n'
  30. console.log(log)
  31. }
  32. function startRenderer () {
  33. return new Promise((resolve, reject) => {
  34. rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
  35. rendererConfig.mode = 'development'
  36. const compiler = webpack(rendererConfig)
  37. hotMiddleware = webpackHotMiddleware(compiler, {
  38. log: false,
  39. heartbeat: 2500
  40. })
  41. compiler.hooks.compilation.tap('compilation', compilation => {
  42. compilation.hooks.htmlWebpackPluginAfterEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
  43. hotMiddleware.publish({ action: 'reload' })
  44. cb()
  45. })
  46. })
  47. compiler.hooks.done.tap('done', stats => {
  48. logStats('Renderer', stats)
  49. })
  50. const server = new WebpackDevServer(
  51. compiler,
  52. {
  53. contentBase: path.join(__dirname, '../'),
  54. quiet: true,
  55. hot: true,
  56. before (app, ctx) {
  57. // app.use(hotMiddleware)
  58. ctx.middleware.waitUntilValid(() => {
  59. resolve()
  60. })
  61. }
  62. }
  63. )
  64. server.listen(9080)
  65. })
  66. }
  67. function startMain () {
  68. return new Promise((resolve, reject) => {
  69. mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
  70. mainConfig.mode = 'development'
  71. const compiler = webpack(mainConfig)
  72. compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
  73. logStats('Main', chalk.white.bold('compiling...'))
  74. hotMiddleware.publish({ action: 'compiling' })
  75. done()
  76. })
  77. compiler.watch({}, (err, stats) => {
  78. if (err) {
  79. console.log(err)
  80. return
  81. }
  82. logStats('Main', stats)
  83. if (electronProcess && electronProcess.kill) {
  84. manualRestart = true
  85. process.kill(electronProcess.pid)
  86. electronProcess = null
  87. startElectron()
  88. setTimeout(() => {
  89. manualRestart = false
  90. }, 5000)
  91. }
  92. resolve()
  93. })
  94. })
  95. }
  96. function startElectron () {
  97. var args = [
  98. '--inspect=5858',
  99. path.join(__dirname, '../dist/electron/main.js')
  100. ]
  101. // detect yarn or npm and process commandline args accordingly
  102. if (process.env.npm_execpath.endsWith('yarn.js')) {
  103. args = args.concat(process.argv.slice(3))
  104. } else if (process.env.npm_execpath.endsWith('npm-cli.js')) {
  105. args = args.concat(process.argv.slice(2))
  106. }
  107. electronProcess = spawn(electron, args)
  108. electronProcess.stdout.on('data', data => {
  109. electronLog(data, 'blue')
  110. })
  111. electronProcess.stderr.on('data', data => {
  112. electronLog(data, 'red')
  113. })
  114. electronProcess.on('close', () => {
  115. if (!manualRestart) process.exit()
  116. })
  117. }
  118. function electronLog (data, color) {
  119. let log = ''
  120. data = data.toString().split(/\r?\n/)
  121. data.forEach(line => {
  122. log += ` ${line}\n`
  123. })
  124. if (/[0-9A-z]+/.test(log)) {
  125. console.log(
  126. chalk[color].bold('┏ Electron -------------------') +
  127. '\n\n' +
  128. log +
  129. chalk[color].bold('┗ ----------------------------') +
  130. '\n'
  131. )
  132. }
  133. }
  134. function greeting () {
  135. const cols = process.stdout.columns
  136. let text = ''
  137. if (cols > 104) text = 'electron-vue'
  138. else if (cols > 76) text = 'electron-|vue'
  139. else text = false
  140. if (text) {
  141. say(text, {
  142. colors: ['yellow'],
  143. font: 'simple3d',
  144. space: false
  145. })
  146. } else console.log(chalk.yellow.bold('\n electron-vue'))
  147. console.log(chalk.blue(' getting ready...') + '\n')
  148. }
  149. function init () {
  150. greeting()
  151. Promise.all([startRenderer(), startMain()])
  152. .then(() => {
  153. startElectron()
  154. })
  155. .catch(err => {
  156. console.error(err)
  157. })
  158. }
  159. init()