hello koa

337356674 8年前

来自: http://www.jianshu.com/p/4603d4ed9a8b


NodeJS平台上最热门的框架莫非express了,但是似乎没有用到es6中的优势语法,于是express团队又搞了一个叫koa的框架,支持es6,所以长远地看,选择koa才是王道。
对于我这样一个很少写js的人来说,一上手就开始使用koa,其实学习难度的曲线挺陡峭的,那再陡峭也得往上爬啊。。。

首先和koa认识一下,从这篇文档中我们可以大致了解到koa是一个极简的框架,连路由的功能都需要借助于第三方中间件。啥叫中间件?我目前的理解就是一个功能插件。使用koa-generator来新建一个项目试试看。

项目建好之后,打开项目根目录下的app.js:

var app = require('koa')()      // 导入中间件      , 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');    // 设置views的目录和所使用的模板  app.use(views('views', {      root: __dirname + '/views',      default: 'jade'  }));  // 加入解析post请求中body的中间件  app.use(require('koa-bodyparser')());  // 加入解析json的中间件  app.use(json());  // 加入log记录的中间件  app.use(logger());    // 收到请求时,先执行这个generator方法  app.use(function *(next){      // 记录开始的时间      var start = new Date;      // 挂起并执行next      yield next;      // 执行完next继续执行,记录耗时并打印      var ms = new Date - start;      console.log('%s %s - %s', this.method, this.url, ms);  });    // 设置静态资源目录  app.use(require('koa-static')(__dirname + '/public'));    // 定义路由  koa.use('/', index.routes(), index.allowedMethods());  koa.use('/users', users.routes(), users.allowedMethods());    // 使路由生效  app.use(koa.routes());    // 监听错误  app.on('error', function(err, ctx){      log.error('server error', err, ctx);  });    module.exports = app;

稍微做了一些注释,可以看到app.js中都是项目设置的逻辑。

首先看看路由功能。

先将路由类导入

// 路由  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());

此时我们访问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;

发现router.get方法的第一个参数是'/',那么是否意味着get的第一个参数中可以省去'/users'?做个实验:

将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。

那么前面的猜想被证实了,那路由的逻辑我们就可以新建一个js来实现,而不需要修改app.js代码,如此整体的项目结构也就清晰了。

在app.js中加入当前项目的路由类:test.js

var app = require('koa')()      // 导入中间件      , 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');    // 设置views的目录和所使用的模板  app.use(views('views', {      root: __dirname + '/views',      default: 'jade'  }));  // 加入解析post请求中body的中间件  app.use(require('koa-bodyparser')());  // 加入解析json的中间件  app.use(json());  // 加入log记录的中间件  app.use(logger());    // 收到请求时,先执行这个generator方法  app.use(function *(next){      // 记录开始的时间      var start = new Date;      // 挂起并执行next      yield next;      // 执行完next继续执行,记录耗时并打印      var ms = new Date - start;      console.log('%s %s - %s', this.method, this.url, ms);  });    // 设置静态资源目录  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());    // 监听错误  app.on('error', function(err, ctx){      log.error('server error', err, ctx);  });    module.exports = app;

如此,所有127.0.0.1:3000/test开始的地址都将被路由到test.js中。