1、koa介绍
koa是一个相对于express来说,更小,更健壮,更富表现力的Web框架。koa通过组合不同的generator来避免繁琐的回调函数调用。koa的核心库没有绑定任何的中间件,仅仅提供了一个轻量优雅的函数库,使得编写Web应用变得得心应手。
1-1、使用koa
在项目目录路径下运行命令
npm install --save-dev koa
就可以在本地安装koa模块。 安装完成后,写一个hello world来验证是否生效。 hello world代码十分简单。
const koa = require('koa');
const app = koa();
app.use(function *(ctx) {
ctx.body = 'hello world';
});
app.listen(3000)
上面代码就实现了koa的helloworld。
第4行调用的app.use()传入了一个generator方法,就是koa中间件的基本实现。
koa应用的实现就是由一个一个的中间件来实现。每一个中间件都是一个generator方法,通过yield语句,将一个一个中间件逻辑级联起来
2、koa源码
koa.js的源码有4个文件,分别是
- lib/application.js
- lib/context.js
- lib/request.js
- lib/response.js。
从名字中可以看出来,context.js,request.js,response.js分别是上下文环境对象,request对象,response对象,而application.js就是koa.js的核心代码。
在上面的例子中,都使用了两个接口,use和listen。下面我们先介绍下这两个方法, 下面是application.js中这两个方法的源码:
// ...
app.listen = function(){
debug('listen');
var server = http.createServer(this.callback());
return server.listen.apply(server, arguments);
};
// ...
app.use = function(fn){
if (!this.experimental) {
// es7 async functions are not allowed,
// so we have to make sure that `fn` is a generator function
assert(fn && 'GeneratorFunction' == fn.constructor.name, 'app.use() requires a generator function');
}
debug('use %s', fn._name || fn.name || '-');
this.middleware.push(fn);
return this;
};
// ...
可以看出来,use的作用就是将传入的中间件generator方法放到this.middleware中。listen接口的作用其实就是启动了一个server,并将请求处理设置为 this.callback()的返回方法。 然后我们来看下this.callback怎么写的:
// ...
app.callback = function(){
if (this.experimental) {
console.error('Experimental ES7 Async Function support is deprecated. Please look into Koa v2 as the middleware signature has changed.')
}
var fn = this.experimental
? compose_es7(this.middleware)
: co.wrap(compose(this.middleware));
var self = this;
if (!this.listeners('error').length) this.on('error', this.onerror);
return function(req, res){
res.statusCode = 404;
var ctx = self.createContext(req, res);
onFinished(res, ctx.onerror);
fn.call(ctx).then(function () {
respond.call(ctx);
}).catch(ctx.onerror);
}
};
// ...
其中的核心代码是这两句:
// ...
co.wrap(compose(this.middleware));
// ...
return function(req, res){
// ...
fn.call(ctx).then(function () {
respond.call(ctx);
}).catch(ctx.onerror);
}
// ...
其中compose(this.middleware)的作用是将传入的中间件数组合并成层层调用的generator函数。co.wrap()方法的作用是将generator数转化成一个自执行的函数。最后的fn.call(ctx)就开始逐步执行中间件了。
3、koa常用中间件
koa框架本身的功能十分简单,koa应用的功能都是通过中间件来实现的,下面我们来介绍常用的几个koa中间件。
3-1、 koa-static
koa-static是管理静态文件请求的中间件。比如要请求html,JS,图片的静态文件时,就可以使用koa-static来实现。 举个例子,比如项目根目录下得static目录用于存放静态文件,那么如下代码就可以实现该目录的静态文件请求
const path = require('path');
const staticServer = require('koa-static');
app.use(staticServer(path.join(__dirname, 'static')));
3-2、koa-router
koa-router是一个路由中间件,用法如下:
const router = require('koa-router')();
// 监听url请求
router.get('/list', function *() {
// ...
});
router.post('/user/register', function *() {
// ...
});
3-3、koa-session
session管理的中间件,用法:
const session = require('koa-session');
app.use(session(app));
router.post('./user/login', function *() {
this.session.user = user;
});