把Koa 2.x写的跟express一样
发布于 8 年前 作者 i5ting 4328 次浏览 来自 分享

ekoa:我想把Koa 2.x写的跟express一样

koa 2.x use express-style middlewares

gitter NPM version Build codecov.io js-standard-style

Features

  • app.use = app.em = app.expressmiddleware 支持Express风格的中间件
  • app._use 依然可以使用Koa 2.x的三种中间件

Install

$ npm i -S ekoa

Usages

const Koa = require('ekoa')
const app = new Koa()

// log1
app.use(function(req, res, next){
  const start = new Date();
  return next().then(() => {
    const ms = new Date() - start;
    console.log(`${req.method} ${req.url} - ${ms}ms`);
  });
})

// log2
app.use(function(req, res, next){
  console.log('start')
  next()
})

app.use(function(req, res, next){
  console.log('process')
  res.body = "Hello Koa 1";
})

// response
app._use(ctx => {
  ctx.body = 'Hello Koa 2'
})

app.run(4000)

支持async函数

const Koa = require('.')
const app = new Koa('sss',{})

// log1
app.use(async function(req, res, next){
  const start = new Date();
  await next()
  
  const ms = new Date() - start;
  console.log(`${req.method} ${req.url} - ${ms}ms`);
})

// log2
app.use(async function(req, res, next){
  console.log('start')
  await next()
})

app.use(function(req, res, next){
  console.log('process')
  res.body = "Hello Koa 1";
})

// response
app._use(ctx => {
  ctx.body = 'Hello Koa 2'
})

app.run(4000)

通过runkoa执行即可(或babel,或者node 7+)

可使用的express风格的中间件

app.em = app.expressmiddleware

正常写法

function(req, res, next){
  console.log('start')
  
  return next().then(function (){
    console.log('end')
  })
}

next和koa commonfunction中的next是一样的。

更简单的写法

app.use(function(req, res, next){
  console.log('start')
  next()
})

中间件正常写法

function(req, res){
  res.body = "xxx"
}

此种写法有先后顺序,没有next中间件就不会向下传递。

源码

刨除注释,不过20行。。。


'use strict'

/**
 * Module dependencies.
 */

const Koa = require('koa')

/**
 * Expose `Application` class.
 * Inherits from `Emitter.prototype`.
 */

module.exports = class EKoa extends Koa {

  /**
   * Initialize a new `Application`.
   *
   * @api public
   */

  constructor () {
    super()

    this.run = this.start = this.listen

    this._use = this.use

    let app = this

    this.use = this.em = this.expressmiddleware = (fn) => {
      if (fn.length <= 3) {
        return app._use((ctx, next) => {
          var req = ctx.req
          var res = ctx.response

          fn.call(this, req, res, next)
        })
      }

      throw new new TypeError('You may only use express-style middleware or koa 2.x middleware!')
    }
  }
}

知识点

  • 面向对象里的继承,即super用法
  • fn.call

写着玩的,基本雏形算是有了。koa和express里的req和res差异较大,当然也不是不能替,所以想玩的话,还是有很多想象空间的。

2 回复

刚入坑,mark

竟然也支持async函数,哇哈哈

回到顶部