UNPKG

4.64 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const KoaRouter = require("koa-router");
4const fs = require("fs");
5const logger_1 = require("./logger");
6const HASLOADED = Symbol('hasloaded');
7class Loader {
8 constructor(app) {
9 this.controller = {};
10 this.koaRouter = new KoaRouter;
11 this.app = app;
12 }
13 appDir() {
14 const subString = removeString(__dirname, 'node_modules');
15 if (subString.isFound) {
16 return subString.source;
17 }
18 return subString.source.substr(0, subString.source.length - 4);
19 }
20 fileLoader(url) {
21 const merge = this.appDir() + url;
22 return fs.readdirSync(merge).map((name) => {
23 return {
24 module: require(merge + '/' + name),
25 filename: name
26 };
27 });
28 }
29 convertController(ctler, funcNames) {
30 const tmp = {};
31 funcNames.forEach((name) => {
32 if (name !== 'constructor') {
33 tmp[name] = {
34 class: ctler,
35 funcName: name
36 };
37 }
38 });
39 return tmp;
40 }
41 loadController() {
42 const controllers = this.fileLoader('app/controller');
43 controllers.forEach((mod) => {
44 const names = Object.getOwnPropertyNames(mod.module.prototype);
45 Object.defineProperty(this.controller, mod.module.name.toLowerCase(), {
46 value: this.convertController(mod.module, names)
47 });
48 });
49 }
50 loadRouter() {
51 const routerUrl = this.appDir() + 'app/router.js';
52 const routing = require(routerUrl)({
53 controller: this.controller
54 });
55 Object.keys(routing).forEach((key) => {
56 const [method, url] = key.split(' ');
57 const d = routing[key];
58 this.koaRouter[method](url, async (ctx) => {
59 const instance = new d.class(ctx, this.app);
60 await instance[d.funcName]();
61 });
62 });
63 this.app.use(this.koaRouter.routes());
64 }
65 loadToContext(target, app, property) {
66 Object.defineProperty(app.context, property, {
67 get() {
68 if (!this[HASLOADED]) {
69 this[HASLOADED] = {};
70 }
71 const loaded = this[HASLOADED];
72 if (!loaded[property]) {
73 loaded[property] = {};
74 target.forEach((mod) => {
75 const key = mod.filename.split('.')[0];
76 loaded[property][key] = new mod.module(this, app);
77 });
78 return loaded.service;
79 }
80 return loaded.service;
81 }
82 });
83 }
84 loadService() {
85 const service = this.fileLoader('app/service');
86 this.loadToContext(service, this.app, 'service');
87 }
88 loadMiddleware() {
89 try {
90 const middleware = this.fileLoader('app/middleware');
91 const registedMid = this.app.config['middleware'];
92 if (!registedMid)
93 return; //如果中间件不存在
94 registedMid.forEach((name) => {
95 logger_1.default.blue(name);
96 for (const index in middleware) {
97 const mod = middleware[index];
98 const fname = mod.filename.split('.')[0];
99 if (name === fname) {
100 this.app.use(mod.module());
101 }
102 }
103 });
104 }
105 catch (e) { }
106 }
107 loadConfig() {
108 const configDef = this.appDir() + 'app/config/config.default.js';
109 const configEnv = this.appDir()
110 + (process.env.NODE_ENV === 'production' ? 'app/config/config.pro.js' : 'app/config/config.dev.js');
111 const conf = require(configEnv);
112 const confDef = require(configDef);
113 const merge = Object.assign({}, conf, confDef);
114 Object.defineProperty(this.app, 'config', {
115 get: () => {
116 return merge;
117 }
118 });
119 }
120 load() {
121 this.loadController();
122 this.loadService();
123 this.loadConfig();
124 this.loadMiddleware();
125 this.loadRouter(); //依赖loadController
126 }
127}
128exports.Loader = Loader;
129function removeString(source, str) {
130 const index = source.indexOf(str);
131 if (index > 0) {
132 return {
133 source: source.substr(0, index),
134 isFound: true
135 };
136 }
137 return {
138 source: source,
139 isFound: false
140 };
141}