koa,了解一下?

1,387 阅读3分钟

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;
});