Node.js 框架对比之 Express VS Koa

介绍

提到 Node.js 开发,不得不提目前煊赫一时的两大框架 Express 和 Koa。 web

Express 诞生已有时日, 是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,主要基于 Connect 中间件,而且自身封装了路由、视图处理等功能,使用人数众多。 express

Koa 相对更为年轻, 是 Express 原班人马基于 ES7 新特性从新开发的框架,框架自身不包含任何中间件,不少功能须要借助第三方中间件解决,可是因为其基于 ES7 async 特性的异步流程控制,解决了 "callback hell" 和麻烦的错误处理问题,大受开发者欢迎。Koa 目前已经升级到了 2.x,如下代码示例都会使用 Koa 2.x。app

示例

Hello World

二者建立一个基础的 Web 服务都很是简单,写法也基本相同,最大的区别是路由处理 Express 是自身集成的,而 Koa 须要引入中间件。框架

// Express
const express = require('express')
const app = express()

app.get('/', function (req, res) {
  res.send('Hello Express')
})

app.listen(3000)
// Koa
const Koa = require('koa')
const route = require('koa-route')

const app = new Koa()

app.use(route.get('/', async (ctx) => {
  ctx.body = 'Hello Koa'
}))

app.listen(3000)

Views

Express 自身集成了视图功能,提供了 consolidate.js 功能,支持几乎全部 JavaScript 模板引擎,并提供了视图设置的便利方法。
Koa 须要引入 koa-views 中间件。koa

// Express
const express = require('express')
const app = express()

app.set('views', __dirname + '/views')
app.set('view engine', 'pug')

app.get('/', function (req, res) {
  res.render('index', {
    title: 'Express'
  })
})
// Koa
const Koa = require('koa')
const route = require('koa-route')
const views = require('koa-views')
const app = new Koa()

app.use(views(path.join(__dirname, './views'), {
  extension: 'pug'
}))

app.use(route.get('/', async (ctx) => {
  await ctx.render('index', {
    title: 'Koa'
  })
}))

区别

中间件模型

Koa 的中间件采用了洋葱圈模型,全部的请求在通过中间件的时候都会执行两次,可以很是方便的执行一些后置处理逻辑。
例如,咱们常常须要计算一个请求的响应时间,在 Koa 中, 咱们能够在中间件的开始记录初始时间,当响应返回时,代码执行又回到了原来的中间件,此时根据当前时间和初始时间的时间差便获得了响应时间。异步

function responseTime() {
  return async function responseTime(ctx, next) {
    const start = Date.now()
    await next() // wait for other middleware to run
    const delta = Math.ceil(Date.now() - start)
    ctx.set('X-Response-Time', delta + 'ms')
  })
}}

而在 Express 中,响应返回时代码执行并不会回到原来的中间件,此时咱们须要经过监听 response.writeHead得到响应返回的时机:socket

const onHeaders = require('on-headers')
function responseTime () {
  return function responseTime (req, res, next) {
    const startAt = process.hrtime()

    onHeaders(res, function onHeaders () {
      const diff = process.hrtime(startAt)
      const time = diff[0] * 1e3 + diff[1] * 1e-6
      res.setHeader('X-Response-Time', time + 'ms')
    })

    next()
  }
}

异常处理

Express 使用 Node 约定的 "error-first 回调" 处理异常,并经过中间件传播。
Koa 经过同步方式编写异步代码,能够经过 try catch 处理异常,很是天然。async

// Express
app.use(function (err, req, res, next) {
  res.status(err.status || 500).send('error')
})
// Koa
app.use(async (ctx, next) => {
  try {
    await next()
  } catch (err) {
    ctx.app.emit('error', err)
    ctx.status = err.status || 500
    ctx.body = { message: err.message }
  }
})

Context

Koa 新增了一个 Context 对象,用来代替 Express 中的 Request 和 Response,做为请求的上下文对象。
Context 上除了 Request 和 Response 两个对象以外,还有 Node.js 原生提供的 req 、res、socket 等对象。ui

相关文章
相关标签/搜索