diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..5226e22 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,30 @@ +declare module '@gm5/core' { + import { Server } from 'http' + + interface Middleware { + (req: Request, res: Response, next: () => void): void + } + + interface Installable { + name: string + install: (args: any) => any + } + + class Five { + get server(): Server + + set(obj: Config): this + + get(key: string): any + + use(fn: Middleware): this + + install(module: Installable, args: any): this + + preload(dir: string): this + + listen(port?: number, callback?: () => void): this + } + + export function createApp(conf?: object): Five +} diff --git a/index.js b/index.js index 01a742c..5c63859 100644 --- a/index.js +++ b/index.js @@ -28,11 +28,15 @@ class Five { #middlewares = [createCors()] #server = null + #online = false constructor() { readonlyProp(this, 'state', Object.create(null)) } + /** + * 循环顺序执行中间件, 直到执行完所有中间件或没有调用next + */ async #loop(req, res, idx = 0) { let fn = this.#middlewares[idx] if (fn) { @@ -43,6 +47,12 @@ class Five { } } + // 注入实例化对象到实例池中 + #install({ name, install }, args) { + this['$$' + name] = install.call(this, args) + return this + } + /*------------------------------------------------------------------------*/ get server() { @@ -76,23 +86,34 @@ class Five { return this.#config[key] } - // 加载中间件 - // 与别的中间件用法有些不一样, 回调的传入参数中的req和res, - // 并非原生的request对象和response对象, - // 而是框架内部封装过的,可通过origin属性访问原生的对象 - use(fn = noop) { - if (typeof fn === 'function') { - this.#middlewares.push(fn) - return this + /** + * 加载中间件 + * 与别的中间件用法有些不一样, 回调的传入参数中的req和res, + * 并非原生的request对象和response对象, + * 而是框架内部封装过的,可通过origin属性访问原生的对象 + * @param {*} middleware + * @returns Five + */ + use(middleware = noop, args) { + if (this.#online) { + return console.error('Server already started, cannot use middleware') } - throw TypeError('argument must be a function') + if (typeof middleware === 'function') { + this.#middlewares.push(middleware) + } else if (typeof middleware === 'object' && typeof middleware.install === 'function') { + this.#install(middleware, args) + } else { + throw TypeError('argument must be a function or installable object') + } + return this } - // 注入实例化对象到实例池中 - // 与use方法不同的是, 这个会在server创建之前就已经执行 - install({ name, install }, args) { - this['$$' + name] = install.call(this, args) - return this + /** + * 注入中间件, 与use方法不同, install方法会立即执行 + * @deprecated 请使用use方法, 将在下个版本中移除 + */ + install(middleware, args) { + return this.#install(middleware, args) } // 预加载应用, 缓存以提高性能 @@ -128,12 +149,11 @@ class Five { } // 启动http服务 - listen(port) { + listen(port = 3000, callback = noop) { this.set({ port }) - return this - } - run() { + this.#online = true + this.#server = http.createServer() // 路由中间件要在最后 @@ -151,14 +171,15 @@ class Five { .on('listening', _ => { if (this.get('debug')) { console.log('Server successfully started ...') - console.log('%s://%s:%d\n', 'http', '127.0.0.1', this.get('port')) + console.log('%s://%s:%d\n', 'http', '127.0.0.1', port) } }) .on('error', err => { console.error(err) }) - .listen(this.get('port')) + .listen(port) + callback.call(this, this.#server) return this } } diff --git a/package.json b/package.json index 4f41452..40d2c67 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "description": "Five.js, 一个轻量级的nodejs mvc框架 旨在简单易用, 5分钟即可上手", "author": "yutent ", "main": "index.js", + "types": "index.d.ts", "dependencies": { "@gm5/session": "^2.0.0", "@gm5/request": "^2.0.3",