框架提供了多種擴(kuò)展點(diǎn)擴(kuò)展自身的功能:
在開(kāi)發(fā)中,我們既可以使用已有的擴(kuò)展 API 來(lái)方便開(kāi)發(fā),也可以對(duì)以上對(duì)象進(jìn)行自定義擴(kuò)展,進(jìn)一步加強(qiáng)框架的功能。
app 對(duì)象指的是 Koa 的全局應(yīng)用對(duì)象,全局只有一個(gè),在應(yīng)用啟動(dòng)時(shí)被創(chuàng)建。
框架會(huì)把 app/extend/application.js 中定義的對(duì)象與 Koa Application 的 prototype 對(duì)象進(jìn)行合并,在應(yīng)用啟動(dòng)時(shí)會(huì)基于擴(kuò)展后的 prototype 生成 app 對(duì)象。
例如,我們要增加一個(gè) app.foo() 方法:
// app/extend/application.js |
一般來(lái)說(shuō)屬性的計(jì)算只需要進(jìn)行一次,那么一定要實(shí)現(xiàn)緩存,否則在多次訪問(wèn)屬性時(shí)會(huì)計(jì)算多次,這樣會(huì)降低應(yīng)用性能。
推薦的方式是使用 Symbol + Getter 的模式。
例如,增加一個(gè) app.bar 屬性 Getter:
// app/extend/application.js |
Context 指的是 Koa 的請(qǐng)求上下文,這是 請(qǐng)求級(jí)別 的對(duì)象,每次請(qǐng)求生成一個(gè) Context 實(shí)例,通常我們也簡(jiǎn)寫(xiě)成 ctx。在所有的文檔中,Context 和 ctx 都是指 Koa 的上下文對(duì)象。
框架會(huì)把 app/extend/context.js 中定義的對(duì)象與 Koa Context 的 prototype 對(duì)象進(jìn)行合并,在處理請(qǐng)求時(shí)會(huì)基于擴(kuò)展后的 prototype 生成 ctx 對(duì)象。
例如,我們要增加一個(gè) ctx.foo() 方法:
// app/extend/context.js |
一般來(lái)說(shuō)屬性的計(jì)算在同一次請(qǐng)求中只需要進(jìn)行一次,那么一定要實(shí)現(xiàn)緩存,否則在同一次請(qǐng)求中多次訪問(wèn)屬性時(shí)會(huì)計(jì)算多次,這樣會(huì)降低應(yīng)用性能。
推薦的方式是使用 Symbol + Getter 的模式。
例如,增加一個(gè) ctx.bar 屬性 Getter:
// app/extend/context.js |
Request 對(duì)象和 Koa 的 Request 對(duì)象相同,是 請(qǐng)求級(jí)別 的對(duì)象,它提供了大量請(qǐng)求相關(guān)的屬性和方法供使用。
ctx.request |
ctx 上的很多屬性和方法都被代理到 request 對(duì)象上,對(duì)于這些屬性和方法使用 ctx 和使用 request 去訪問(wèn)它們是等價(jià)的,例如 ctx.url === ctx.request.url。
Koa 內(nèi)置的代理 request 的屬性和方法列表:Koa - Request aliases
框架會(huì)把 app/extend/request.js 中定義的對(duì)象與內(nèi)置 request 的 prototype 對(duì)象進(jìn)行合并,在處理請(qǐng)求時(shí)會(huì)基于擴(kuò)展后的 prototype 生成 request 對(duì)象。
例如,增加一個(gè) request.foo 屬性 Getter:
// app/extend/request.js |
Response 對(duì)象和 Koa 的 Response 對(duì)象相同,是 請(qǐng)求級(jí)別 的對(duì)象,它提供了大量響應(yīng)相關(guān)的屬性和方法供使用。
ctx.response |
ctx 上的很多屬性和方法都被代理到 response 對(duì)象上,對(duì)于這些屬性和方法使用 ctx 和使用 response 去訪問(wèn)它們是等價(jià)的,例如 ctx.status = 404 和 ctx.response.status = 404 是等價(jià)的。
Koa 內(nèi)置的代理 response 的屬性和方法列表:Koa Response aliases
框架會(huì)把 app/extend/response.js 中定義的對(duì)象與內(nèi)置 response 的 prototype 對(duì)象進(jìn)行合并,在處理請(qǐng)求時(shí)會(huì)基于擴(kuò)展后的 prototype 生成 response 對(duì)象。
例如,增加一個(gè) response.foo 屬性 setter:
// app/extend/response.js |
就可以這樣使用啦:this.response.foo = 'bar';
Helper 函數(shù)用來(lái)提供一些實(shí)用的 utility 函數(shù)。
它的作用在于我們可以將一些常用的動(dòng)作抽離在 helper.js 里面成為一個(gè)獨(dú)立的函數(shù),這樣可以用 JavaScript 來(lái)寫(xiě)復(fù)雜的邏輯,避免邏輯分散各處。另外還有一個(gè)好處是 Helper 這樣一個(gè)簡(jiǎn)單的函數(shù),可以讓我們更容易編寫(xiě)測(cè)試用例。
框架內(nèi)置了一些常用的 Helper 函數(shù)。我們也可以編寫(xiě)自定義的 Helper 函數(shù)。
通過(guò) ctx.helper 訪問(wèn)到 helper 對(duì)象,例如:
// 假設(shè)在 app/router.js 中定義了 home router |
框架會(huì)把 app/extend/helper.js 中定義的對(duì)象與內(nèi)置 helper 的 prototype 對(duì)象進(jìn)行合并,在處理請(qǐng)求時(shí)會(huì)基于擴(kuò)展后的 prototype 生成 helper 對(duì)象。
例如,增加一個(gè) helper.foo() 方法:
// app/extend/helper.js |
另外,還可以根據(jù)環(huán)境進(jìn)行有選擇的擴(kuò)展,例如,只在 unittest 環(huán)境中提供 mockXX() 方法以便進(jìn)行 mock 方便測(cè)試。
// app/extend/application.unittest.js |
這個(gè)文件只會(huì)在 unittest 環(huán)境加載。
同理,對(duì)于 Application,Context,Request,Response,Helper 都可以使用這種方式針對(duì)某個(gè)環(huán)境進(jìn)行擴(kuò)展,更多參見(jiàn)運(yùn)行環(huán)境。
更多建議: