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;
});
複製程式碼