mirror of
https://github.com/roleypoly/roleypoly-v1.git
synced 2025-04-25 12:19:10 +00:00
backend: router hot-reloading
This commit is contained in:
parent
11cf1d4805
commit
959a2eb46f
4 changed files with 53 additions and 20 deletions
40
Roleypoly.js
40
Roleypoly.js
|
@ -3,16 +3,17 @@ const Sequelize = require('sequelize')
|
|||
const fetchModels = require('./models')
|
||||
const fetchApis = require('./api')
|
||||
const Next = require('next')
|
||||
|
||||
const betterRouter = require('koa-better-router')
|
||||
|
||||
class Roleypoly {
|
||||
constructor (router, io, app) {
|
||||
this.router = router
|
||||
constructor (io, app) {
|
||||
this.io = io
|
||||
this.ctx = {}
|
||||
|
||||
this.ctx.config = {
|
||||
appUrl: process.env.APP_URL
|
||||
appUrl: process.env.APP_URL,
|
||||
dev: process.env.NODE_ENV !== 'production',
|
||||
hotReload: process.env.NO_HOT_RELOAD !== '1'
|
||||
}
|
||||
|
||||
this.ctx.io = io
|
||||
|
@ -52,10 +53,11 @@ class Roleypoly {
|
|||
this.ctx.P = new (require('./services/presentation'))(this.ctx)
|
||||
}
|
||||
|
||||
async mountRoutes () {
|
||||
async loadRoutes (forceClear = false) {
|
||||
await this.ctx.ui.prepare()
|
||||
|
||||
fetchApis(this.router, this.ctx)
|
||||
this.router = betterRouter().loadMethods()
|
||||
fetchApis(this.router, this.ctx, { forceClear })
|
||||
|
||||
// after routing, add the * for ui handler
|
||||
this.router.get('*', async ctx => {
|
||||
|
@ -63,7 +65,31 @@ class Roleypoly {
|
|||
ctx.respond = false
|
||||
})
|
||||
|
||||
this.__app.use(this.router.middleware())
|
||||
return this.router.middleware()
|
||||
}
|
||||
|
||||
async mountRoutes () {
|
||||
let mw = await this.loadRoutes()
|
||||
|
||||
if (this.ctx.config.dev && this.ctx.config.hotReload) {
|
||||
// hot-reloading system
|
||||
log.info('API hot-reloading is active.')
|
||||
const chokidar = require('chokidar')
|
||||
let hotMiddleware = mw
|
||||
|
||||
this.__apiWatcher = chokidar.watch('api/**')
|
||||
this.__apiWatcher.on('all', async (path) => {
|
||||
log.info('reloading APIs...', path)
|
||||
hotMiddleware = await this.loadRoutes(true)
|
||||
})
|
||||
|
||||
// custom passthrough so we use a specially scoped middleware.
|
||||
mw = (ctx, next) => {
|
||||
return hotMiddleware(ctx, next)
|
||||
}
|
||||
}
|
||||
|
||||
this.__app.use(mw)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ const glob = require('glob')
|
|||
|
||||
const PROD = process.env.NODE_ENV === 'production'
|
||||
|
||||
module.exports = async (router, ctx) => {
|
||||
module.exports = async (router, ctx, { forceClear = false } = {}) => {
|
||||
const apis = glob.sync(`./api/**/!(index).js`)
|
||||
log.debug('found apis', apis)
|
||||
|
||||
|
@ -14,7 +14,11 @@ module.exports = async (router, ctx) => {
|
|||
}
|
||||
log.debug(`mounting ${a}`)
|
||||
try {
|
||||
require(a.replace('api/', ''))(router, ctx)
|
||||
const pathname = a.replace('api/', '')
|
||||
if (forceClear) {
|
||||
delete require.cache[require.resolve(pathname)]
|
||||
}
|
||||
require(pathname)(router, ctx)
|
||||
} catch (e) {
|
||||
log.error(`couldn't mount ${a}`, e)
|
||||
}
|
||||
|
|
11
index.js
11
index.js
|
@ -1,13 +1,10 @@
|
|||
require('dotenv').config({silent: true})
|
||||
require('dotenv').config({ silent: true })
|
||||
const log = new (require('./logger'))('index')
|
||||
|
||||
const http = require('http')
|
||||
const Koa = require('koa')
|
||||
const app = new Koa()
|
||||
const _io = require('socket.io')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const router = require('koa-better-router')().loadMethods()
|
||||
const Roleypoly = require('./Roleypoly')
|
||||
const ksuid = require('ksuid')
|
||||
|
||||
|
@ -20,7 +17,7 @@ Array.prototype.areduce = async function (predicate, acc = []) { // eslint-disab
|
|||
return acc
|
||||
}
|
||||
|
||||
Array.prototype.filterNot = Array.prototype.filterNot || function (predicate) {
|
||||
Array.prototype.filterNot = Array.prototype.filterNot || function (predicate) { // eslint-disable-line
|
||||
return this.filter(v => !predicate(v))
|
||||
}
|
||||
|
||||
|
@ -28,9 +25,7 @@ Array.prototype.filterNot = Array.prototype.filterNot || function (predicate) {
|
|||
const server = http.createServer(app.callback())
|
||||
const io = _io(server, { transports: ['websocket'], path: '/api/socket.io' })
|
||||
|
||||
|
||||
|
||||
const M = new Roleypoly(router, io, app) // eslint-disable-line no-unused-vars
|
||||
const M = new Roleypoly(io, app) // eslint-disable-line no-unused-vars
|
||||
|
||||
app.keys = [ process.env.APP_KEY ]
|
||||
|
||||
|
|
14
package.json
14
package.json
|
@ -3,12 +3,13 @@
|
|||
"version": "2.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "pm2 start index.js",
|
||||
"dev": "pm2 start index.js --watch",
|
||||
"build": "next build"
|
||||
"start": "node index.js",
|
||||
"dev": "node index.js",
|
||||
"build": "next build ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"@discordjs/uws": "^11.149.1",
|
||||
"@primer/components": "^10.0.1",
|
||||
"chalk": "^2.4.2",
|
||||
"discord.js": "^11.4.2",
|
||||
"dotenv": "^6.2.0",
|
||||
|
@ -32,5 +33,12 @@
|
|||
"socket.io": "^2.2.0",
|
||||
"superagent": "^4.1.0",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-plugin-transform-flow-strip-types": "^6.22.0",
|
||||
"chokidar": "^2.1.2",
|
||||
"flow-type": "^1.0.1",
|
||||
"standard": "^12.0.1"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue