NodeJS平臺(tái)上最熱門的框架莫非express了,但是似乎沒有用到es6中的優(yōu)勢(shì)語法,于是express團(tuán)隊(duì)又搞了一個(gè)叫koa的框架,支持es6,所以長遠(yuǎn)地看,選擇koa才是王道。
對(duì)于我這樣一個(gè)很少寫js的人來說,一上手就開始使用koa,其實(shí)學(xué)習(xí)難度的曲線挺陡峭的,那再陡峭也得往上爬啊。。。
首先和koa認(rèn)識(shí)一下,從這篇文檔中我們可以大致了解到koa是一個(gè)極簡(jiǎn)的框架,連路由的功能都需要借助于第三方中間件。啥叫中間件?我目前的理解就是一個(gè)功能插件。使用koa-generator來新建一個(gè)項(xiàng)目試試看。
項(xiàng)目建好之后,打開項(xiàng)目根目錄下的app.js:
var app = require('koa')()
// 導(dǎo)入中間件
, koa = require('koa-router')()
, logger = require('koa-logger')
, json = require('koa-json')
, views = require('koa-views')
, onerror = require('koa-onerror');
// 路由
var index = require('./routes/index');
var users = require('./routes/users');
// 設(shè)置views的目錄和所使用的模板
app.use(views('views', {
root: __dirname + '/views',
default: 'jade'
}));
// 加入解析post請(qǐng)求中body的中間件
app.use(require('koa-bodyparser')());
// 加入解析json的中間件
app.use(json());
// 加入log記錄的中間件
app.use(logger());
// 收到請(qǐng)求時(shí),先執(zhí)行這個(gè)generator方法
app.use(function *(next){
// 記錄開始的時(shí)間
var start = new Date;
// 掛起并執(zhí)行next
yield next;
// 執(zhí)行完next繼續(xù)執(zhí)行,記錄耗時(shí)并打印
var ms = new Date - start;
console.log('%s %s - %s', this.method, this.url, ms);
});
// 設(shè)置靜態(tài)資源目錄
app.use(require('koa-static')(__dirname + '/public'));
// 定義路由
koa.use('/', index.routes(), index.allowedMethods());
koa.use('/users', users.routes(), users.allowedMethods());
// 使路由生效
app.use(koa.routes());
// 監(jiān)聽錯(cuò)誤
app.on('error', function(err, ctx){
log.error('server error', err, ctx);
});
module.exports = app;
稍微做了一些注釋,可以看到app.js中都是項(xiàng)目設(shè)置的邏輯。
首先看看路由功能。
先將路由類導(dǎo)入
// 路由
var index = require('./routes/index');
var users = require('./routes/users');
然后定義路由
// 定義路由
koa.use('/', index.routes(), index.allowedMethods());
koa.use('/users', users.routes(), users.allowedMethods());
// 使路由生效
app.use(koa.routes());
此時(shí)我們?cè)L問127.0.0.1:3000就路由到了./routes/index中,訪問127.0.0.1:3000/users就路由到了./routes/users中了。
打開./routes/users.js:
var router = require('koa-router')();
router.get('/', function *(next) {
this.body = 'this a users response!';
});
module.exports = router;
發(fā)現(xiàn)router.get方法的第一個(gè)參數(shù)是'/',那么是否意味著get的第一個(gè)參數(shù)中可以省去'/users'?做個(gè)實(shí)驗(yàn):
將users.js中改為:
var router = require('koa-router')();
router.get('/', function *(next) {
this.body = 'this a users response!';
});
router.get('/test', function *(next) {
this.body = 'this a users test response!';
});
module.exports = router;
訪問127.0.0.1:3000/users/test,瀏覽器中顯示this a users test response!。bingo。
那么前面的猜想被證實(shí)了,那路由的邏輯我們就可以新建一個(gè)js來實(shí)現(xiàn),而不需要修改app.js代碼,如此整體的項(xiàng)目結(jié)構(gòu)也就清晰了。
在app.js中加入當(dāng)前項(xiàng)目的路由類:test.js
var app = require('koa')()
// 導(dǎo)入中間件
, koa = require('koa-router')()
, logger = require('koa-logger')
, json = require('koa-json')
, views = require('koa-views')
, onerror = require('koa-onerror');
// 路由
var index = require('./routes/index');
var users = require('./routes/users');
var test = require('./routes/test');
// db
var db = require('./app/models/db/db');
// 設(shè)置views的目錄和所使用的模板
app.use(views('views', {
root: __dirname + '/views',
default: 'jade'
}));
// 加入解析post請(qǐng)求中body的中間件
app.use(require('koa-bodyparser')());
// 加入解析json的中間件
app.use(json());
// 加入log記錄的中間件
app.use(logger());
// 收到請(qǐng)求時(shí),先執(zhí)行這個(gè)generator方法
app.use(function *(next){
// 記錄開始的時(shí)間
var start = new Date;
// 掛起并執(zhí)行next
yield next;
// 執(zhí)行完next繼續(xù)執(zhí)行,記錄耗時(shí)并打印
var ms = new Date - start;
console.log('%s %s - %s', this.method, this.url, ms);
});
// 設(shè)置靜態(tài)資源目錄
app.use(require('koa-static')(__dirname + '/public'));
// 定義路由
koa.use('/', index.routes(), index.allowedMethods());
koa.use('/users', users.routes(), users.allowedMethods());
koa.use('/test', test.routes(), test.allowedMethods());
// 使路由生效
app.use(koa.routes());
// 監(jiān)聽錯(cuò)誤
app.on('error', function(err, ctx){
log.error('server error', err, ctx);
});
module.exports = app;
如此,所有127.0.0.1:3000/test開始的地址都將被路由到test.js中。