UNPKG

anchundan

Version:
214 lines (206 loc) 7.39 kB
const path = require('path'); const fs = require('fs'); const {getController} = require('anchundan/src/core/corecontroller'); const { setPlugins, initContextPlugins } = require('anchundan/src/core/coreplugins'); const KOA = require('koa'); //const initRouter = require('../middleware/main'); const { setMiddleWares, initCoreMiddleWares } = require('anchundan/src/core/coremiddleware'); const novalueproxy = require('anchundan/src/core/utils/novalueproxy'); const publiccom = require('./publiccom'); const hookType = require('anchundan/src/core/hooks/hookType'); const FrameworkType = require('anchundan/src/core/baseStruct/FrameworkType'); // addExtension 装饰器,为Application增加扩展方法 // @addExtension class Application { constructor(){ if( Application._instance){ throw new Error('Application could not be recrteated'); } this.isstart = false; process.on('uncaughtException',(e)=>{ console.log(`uncaughtException -> ${e.message,e.stack.split('\n')}`); if(this.config && this.config.handleUncaughtException){ this.config.handleUncaughtException.call(null,this,e); } }); process.on('unhandledRejection',(e)=>{ console.log(`unhandledRejection -> ${e.message,e.stack.split('\n')}`); if(this.config && this.config.handleUnhandledRejection){ this.config.handleUnhandledRejection.call(null,this,e); } }); } static getInstance(){ if(!Application._instance){ Application._instance = new Application(); } return Application._instance; } startApp(){ if(this.isstart) return; this.setPlugins({}); this.server = new KOA(); this.server.use(async (ctx,next)=>{ ctx.set('Re-Path',ctx.path); await next(); }); this.middlewares = {}; this.loadConfig(); hookType(path.join(process.getRoot(),'./controller'), FrameworkType.CONTROLLER ); hookType(path.join(process.getRoot(),'./controllers'), FrameworkType.CONTROLLER ); hookType(path.join(__dirname,'./controllers'), FrameworkType.CONTROLLER ); this.controllers = getController(this); //加载controllers hookType(path.join(__dirname,'./plugins'), FrameworkType.PLUGIN ); hookType(path.join(process.getRoot(),'./plugins'), FrameworkType.PLUGIN ); setPlugins(this); //获取插件 initContextPlugins(this); // 实现context插件挂载 // 挂载核心中间件 hookType(path.join(__dirname,'./middleware'), FrameworkType.CORE_MIDDLEWARE ); hookType(path.join(process.getRoot(),'./middleware'), FrameworkType.MIDDLEWARE); hookType(path.join(process.getRoot(),'./middlewares'), FrameworkType.MIDDLEWARE); setMiddleWares(this); //加载中间件 initCoreMiddleWares(this) this.io = null; //获取controller this.server.listen(this.config.port, () => { console.log(`app run at : http://localhost:${this.config.port}`); }); /** * 初始化插件 * 加载plugins * app/start 是用来增加socket 应用而存在的,可以在app/start中增加 脚本,使整个项目和socket 应用整合。 * PS:socket 应用需要增加单独的端口监听,不能和http 公用一个端口。端口的配置可以在config 中自定义的作出配置 */ const appfunsPath = path.join(process.getRoot(),'app/start'); if(fs.existsSync(appfunsPath)) { let list = fs.readdirSync(appfunsPath); list.forEach(_item => { let fun = require(path.join(appfunsPath,_item)); this.setInit(fun); }); } this.isstart = true; } addExtensions(extension) { const { controllers, services, plugins, middlewares, config, routers } = extension; if(config) { hookType(config, FrameworkType.CONFIG); } if(controllers) { hookType(controllers, FrameworkType.CONTROLLER); } if(services) { hookType(services, FrameworkType.SERVICES); } if(plugins) { hookType(plugins, FrameworkType.PLUGIN); } if(middlewares) { hookType(middlewares, FrameworkType.MIDDLEWARE); } if(routers) { hookType(routers, FrameworkType.ROUTER); } } setPlugins(value){ // plugins 是一个 if(!this.plugins){ this.plugins = new Proxy(value,{ get:(target,key)=>{ return target[key]; }, set:(target,key,val)=>{ target[key] = val; return true; } }); } } // setServices(services){ if(!this.services){ this.services =new Proxy(services,{ get:(target,key)=>{ if(target[key]) return target[key]; else return novalueproxy; } }); } } // setControllers(value){ if(!this.controllers){ this.controllers = value; } } loadConfig(){ const extensionsConfig = publiccom.getTarget('types')['config']; let configs = []; const template_pool = {}; if(extensionsConfig){ extensionsConfig.forEach(configPath => configs.push( this.appendConfig(configPath) )) } configs.push(this.appendConfig(path.join(process.getRoot(),"config"))); this.config = {}; configs.forEach(conf=>{ Object.keys(this.config).forEach( key => { if(Array.isArray(this.config[key])){ if(!template_pool[key]) { template_pool[key] = []; } template_pool[key] = template_pool[key].concat(this.config) } } ) this.config = Object.assign(this.config,conf); }) } appendConfig(configPath) { let env = process.env.NODE_ENV || 'dev'; let baseconfig = require(path.join(configPath,'config.base.js')); let env_config = fs.existsSync(path.join(configPath,'config.'+env+'.js')) ? require(path.join(configPath,'config.'+env+'.js')) : {}; return { ...baseconfig, ...env_config } } setInit(func){ func.call(null,this); } } let App = Application.getInstance(); publiccom.regTarget('app',App); module.exports = new Proxy(App,{ get:(target,key)=>{ return target[key] || undefined; }, set:(target,key,value) => { //确保application 的属性值不受污染。 if(target.isstart) { console.warn('new property is not allowed to set in application'); }else{ target[key] = value; } return true; //throw new Error("new property is not allowed to set in application"); } });