UNPKG

3.21 kBJavaScriptView Raw
1const DEFAULT_PORT = 3000
2const DEFAULT_DOMAIN = 'localhost'
3
4const debug = require('debug')
5const warn = debug('SYSTEM:warn')
6const info = debug('SYSTEM:info')
7const error = debug('SYSTEM:error')
8
9export default class AppContainer {
10
11 constructor() {
12
13 // 存放子应用的键值对
14 this.subApps = {}
15
16 // 实例化1个 Koa 对象
17 this.app = ((Koa) => new Koa())(require('koa'))
18 // this.mountSwitchSubAppMiddleware()
19 }
20
21 /**
22 * 挂载子应用,一般是跟进二级域名前缀区分的
23 * 二级域名前缀作为key
24 *
25 * @param {string} key
26 * @param {object} app
27 * @memberof AppContainer
28 */
29 addSubApp(domain, app) {
30
31 if (this.subApps[domain]) {
32 warn(`This app domain is exist : %o , it will be overwrite.`, domain)
33 }
34
35 info(`APP [%o] is mounted √`, domain)
36
37 this.subApps[domain] = app
38 }
39
40 removeSubApp(domain) {
41 this.subApps[domain] = undefined
42 }
43
44 /**
45 * 根据二级域名去执行不同的子 App 逻辑
46 *
47 * @memberof AppContainer
48 */
49 mountSwitchSubAppMiddleware(defaultDomain = DEFAULT_DOMAIN) {
50
51 const compose = require('koa-compose')
52 const me = this
53
54 this.app.use(async function(ctx, next) {
55
56 let domain = ctx.hostname
57
58 // 开发模式可以把以IP访问,默认指向 默认配置app
59
60 if (['localhost', '127.0.0.1'].indexOf(ctx.hostname) > -1) {
61 domain = defaultDomain
62 }
63
64 // 把子应用的逻辑部分合并过来
65
66 if (JSON.stringify(me.subApps) === JSON.stringify({})) return next()
67
68 let subApp = me.subApps[domain]
69 if (subApp) {
70 await compose(subApp.middleware)(ctx)
71 } else {
72 // ctx.redirect(`${ctx.protocol}://${defaultDomain}.${ctx.host}${ctx.path}${ctx.search}`)
73 ctx.status = 404
74 }
75
76 })
77 }
78
79
80 run(port = DEFAULT_PORT) {
81
82 const http = require('http')
83
84 //
85
86 const server = http.createServer(this.app.callback())
87
88 // http 服务监听
89
90 server.on('error', onError)
91 server.on('listening', onListening)
92
93 function onError(err) {
94
95 if (err.syscall !== 'listen') {
96 throw err
97 }
98
99 // handle specific listen errors with friendly messages
100 switch (err.code) {
101 case 'EACCES':
102 error(port + ' requires elevated privileges !!!')
103 process.exit(1)
104 break
105 case 'EADDRINUSE':
106 error(port + ' is already in use !!!')
107 process.exit(1)
108 break
109 default:
110 throw err
111 }
112 }
113
114 function onListening() {
115 info(`SYSTEM listening on ${port} √ `)
116 }
117
118 //
119
120 server.listen(port)
121
122 //
123
124 this.httpServer = server
125 }
126}
\No newline at end of file