app.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. const http = require('http')
  2. const express = require('express')
  3. const morgan = require('morgan')
  4. const bodyParser = require('body-parser')
  5. const chalk = require('chalk')
  6. const config = require('../config')
  7. const expressWs = require('express-ws')
  8. const yargs = require('yargs')
  9. const mode = yargs.argv.mode || 'development'
  10. const app = express()
  11. app.server = http.createServer(app)
  12. expressWs(app, app.server)
  13. if (mode === 'development') {
  14. const webpack = require('webpack')
  15. const webpackDevMiddleware = require('webpack-dev-middleware')
  16. const webpackHotMiddleware = require('webpack-hot-middleware')
  17. const webpackConfig = require('../webpack.config')
  18. const compiler = webpack(webpackConfig)
  19. const devMiddleware = webpackDevMiddleware(compiler, {
  20. noInfo: false,
  21. publicPath: ''
  22. })
  23. app.use((req, res, next) => {
  24. res.set('X-Accel-Buffering', 'no')
  25. next()
  26. })
  27. app.use(devMiddleware)
  28. app.use('/', devMiddleware)
  29. const hotMiddleware = webpackHotMiddleware(compiler, {
  30. path: '/__webpack__/__webpack_hmr'
  31. })
  32. app.use(hotMiddleware)
  33. }
  34. app.use(morgan('combined'))
  35. app.use(bodyParser.json())
  36. app.use(express.static('dist'))
  37. app.listen = (port = config.port || (app.settings.env === 'production' ? 80 : 3000)) => new Promise((resolve, reject) => {
  38. app.server.once('error', (err) => {
  39. if (err.message.includes('EADDRINUSE') && app.settings.env === 'development' && port < 3999) {
  40. console.warn(err.message)
  41. resolve(app.listen(port + 1))
  42. } else {
  43. reject(err)
  44. }
  45. })
  46. app.server.listen(port, () => {
  47. const host = [process.env.HOSTNAME || process.env.COMPUTERNAME || 'localhost', process.env.USERDNSDOMAIN].filter(x => x).join('.').toLowerCase()
  48. const url = `http://${host}:${app.server.address().port}`
  49. console.log(`Server running at ${chalk.underline(chalk.blueBright(url))}`)
  50. if (mode === 'development') {
  51. console.log('Establishing reverse proxy')
  52. const rc = require('persist-proxy/src/reverse-client')
  53. rc({
  54. listen: {
  55. host: '127.0.0.1',
  56. port: port
  57. },
  58. connect: [
  59. {
  60. host: 'www.alanc.net',
  61. port: 8000
  62. },
  63. {
  64. host: '0.0.0.0',
  65. port: port
  66. }
  67. ]
  68. })
  69. }
  70. })
  71. })
  72. const userApp = express.Router()
  73. // Handle unhandled rejection in route handlers:
  74. const appProxy = new Proxy(userApp, {
  75. get: (_, prop) => {
  76. if (prop[0] == '_') return userApp[prop]
  77. const orig = userApp[prop]
  78. if (orig instanceof Function) {
  79. return (...args) => {
  80. const newArgs = args.map(fn => {
  81. if (fn instanceof Function) {
  82. return Object.assign((...args) => {
  83. const ret = fn(...args)
  84. if (ret && ret.catch) {
  85. ret.catch(err => {
  86. const url = args[0] && args[0].url
  87. console.warn(chalk.yellow(`Unhandled Promise Rejection (${url}): ${err}`))
  88. try {
  89. args[1].status(500).send({error: err.toString()})
  90. } catch (err) {
  91. console.warn(chalk.yellow(`Unable to send error response`))
  92. }
  93. })
  94. }
  95. return ret
  96. }, fn)
  97. } else {
  98. return fn
  99. }
  100. })
  101. return userApp[prop](...newArgs)
  102. }
  103. } else {
  104. return orig
  105. }
  106. }
  107. })
  108. appProxy.start = () => {
  109. app.listen().catch(err => {
  110. console.log(chalk.red(err))
  111. process.exit(1)
  112. })
  113. }
  114. app.use(userApp)
  115. userApp._userApp = userApp
  116. userApp._app = app
  117. module.exports = appProxy