前言
再开一坑,学习一下Koa的源码,好在Koa的源码不长且易读,这个坑应该很快能填上。Koa的版本为 2.7.0
Koa的使用
- 安装 Node 环境(Koa 依赖 node v7.6.0 或 ES2015及更高版本和 async 方法支持)
- 安装 Koa: npm i koa
- 创建如下 app.js 文件并运行:node app.js
1
2
3
4
5
6
7
8
9// app.js
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000)
打开浏览器访问 localhost:3000,将会看到 ‘Hello World’.
入口文件application.js
了解了最简单的使用,现在开始分析。
从 koa 的 package.json 文件中可以看到其主入口是 “main”: “lib/application.js”
application.js 暴露出一个 class Application,这个 Application 就是 koa,它继承了 events,让 koa 可以监听与触发事件。
我们以上面的 app.js 为例,开始分析:
new Koa()
1 | module.exports = class Application extends Emitter { |
这一步比较简单,定义了一些属性,将 context、request、response 分别挂在 this.context、this.request、this.response上。
app.use()
1 | use(fn) { |
use 也比较简单,它对入参 fn 做了限制,如果 fn 是 generator 函数的话,会经过 convert() 的转换,最后 push 到 this.middleware 中。
app.listen(3000);
1 | listen(...args) { |
使用 http.createServer 创建 Node 服务,其参数为 this.callback(),下面看下 this.callback 都写了什么:
this.callback
1 | callback() { |
定义 handleRequest 并返回,在 handleRequest 中 定义 ctx
,又执行并返回 this.handleRequest(ctx, fn),
所以 const handleRequest = (req, res) => { // code… } 才是 http.createServer 的参数。
之后 server.listen(…args) 启动了服务,当我们收到服务之后 👇
this.createContext - 创建ctx
1 | createContext(req, res) { // 参数 req、res 是 http.createServer 中得到的 req、res |
createContext 创建了 context,并在 context、request、response 上挂载了各种属性,同时又将 request、response 挂载在 context 上,最后返回。
this.handleRequest(ctx, fn)
1 | handleRequest(ctx, fnMiddleware) { |
主要看这句 fnMiddleware(ctx).then(handleResponse).catch(onerror)
,这里使用 Promise.resolve() 依次执行各中间件,最后执行.then(),结束请求。