解析 Koa2 原理

什么是 koa 框架?

koa 是一个基于 node 实现的一个新的 web 框架,它是由 express 框架的原班人马打造的。它的特点是优雅、简洁、表达力强、自由度高。它更 express 相比,它是一个更轻量的 node 框架,因为它所有功能都通过插件实现,这种插拔式的架构设计模式,很符合 unix 哲学。

学习准备:

  1. Node Http
  2. Promise 对象
  3. async 函数
  4. Class 基本使用
  5. Object

在 koa2 源码中用到许多关于 es6 的语法与新增的属性等,因此如果想要看懂 koa2 的源码,还需要 es6 的一些基础、如是没有可查看阮一峰的ECMAScript 6 入门

Koa 源码结构

00dc2129c72169fa64f2c919dd054d93.png

上图是 Koa2 的源码目录结构的 lib 文件夹,lib 文件夹下放着四个 koa2 核心文件:application.jscontext.jsrequest.jsresponse.js

application.js

application.js 是 koa 的入口文件,它向外导出了创建 class 实例的构造函数,继承了 events,这样就会赋予框架事件监听和事件触发的能力。application 还暴露了一些常用的 api,比如 toJSON、listen,use,createContext 等等。

listen 的实现原理就是将 http.createServer 进行封装,主要是这个函数中可传入 callback,它里面包含了中间件的合并,上下文的处理,对 res 的特殊处理。

use 是收集中间件,将多个中间件放入一个缓存队列中,然后通过 koa-compose 这个插件进行递归组合调用这些队列的中间件。

context.js

context.js 就是 koa 的应用上下文 ctx,其实就是一个简单的对象暴露,重点在 delegate,这个就是代理,为了开发者方便而设计的。例如我们要访问 ctx.repsponse.status 我们可以通过 delegate,就可以直接访问到 ctx.status。

request.js、response.js

这两部分就是对原生的 res、req 的一些操作了,大量使用了 es6 的 get 和 set 的一些语法,去取 headers 或者设置 headers、还有设置 body,这个就不详细介绍了,各位有兴趣的话可以去看源码。

实现 koa2 的四大模块

上面讲述了 koa2 源码的大体框架结构,接下来我们来实现一个 koa2 的框架,认为理解和实现一个 koa 框架需要实现四大模块,分别是:

  • 封装 node http server、创建 Koa 类构造函数
  • 构造 request、resopnse、context 对象
  • 中间件机制和剥洋葱模型的实现
  • 错误捕获和错误处理

下面我们就逐一分析和实现。

模块一:封装 node http server 和创建 Koa 类构造函数

阅读 koa2 的源码得知,实现 koa 的服务器应用和端口监听,其实就是基于 node 的原生代码进行了封装,如下图的代码就是通过 node 原生代码实现的服务器监听。

1
2
3
4
5
6
7
8
let http = require("http");
let server = http.createServer((req, res) => {
res.writeHead(200);
res.end("hello world");
});
server.listen(3000, () => {
console.log("listenning on 3000");
});

我们需要将上面的 node 原生代码封装实现成 koa 的模式:

1
2
3
4
const http = require("http");
const Koa = require("koa");
const app = new Koa();
app.listen(3000);

实现 koa 的第一步就是对以上的这个过程进行封装,为此我们需要创建 application.js 实现一个 Application 类的构造函数:

9fe42b3fc46aa62867b9411e80b276ae.png

然后创建 example.js,引入 application.js,运行服务器实例启动监听代码:

faef6b84c91d768c54ad366361acd254.png

运行结果:

3e9c2275b57dc0ca6a6acaaee72cc037.png

现在我们第一步已经完成了,对 http server 进行了简单的封装和创建了一个可以生成 koa 实例的类 class,这个类还实现了 app.use 用来注册中间件和注册回调函数,app.listen 用来开启服务器实例并传入回调函数,第一模块主要是实现典型的 koa 风格和搭好一个 koa 的简单架子。接下来我们开始编写和讲解第二模块。

模块二:构造 request、response、context 对象
-------------本文结束感谢您的阅读-------------