下一代web框架Koa

  1. const Koa = require('koa')
  2. const app = new Koa()
  3. // 日志中间件
  4. app.use(async (ctx, next) => {
  5. const start = new Date()
  6. console.log('before wait');
  7. await next()
  8. console.log('after wait');
  9. const ms = new Date() - start
  10. console.log(`${ctx.method} ${ctx.url} ${ms}ms`);
  11. })
  12. // 响应
  13. app.use(async ctx => {
  14. console.log('response');
  15. ctx.body = 'Hello Koa 2'
  16. })
  17. app.listen(3000)

koa-generator

koa-generator 提供的功能:

  • 生成项目骨架,集成必要的中间件
  • 约定目录结构
    • app.js为入口
    • bin/www为启动入口
    • 支持静态服务器,即 public 目录
    • 支持 routes 目录
    • 支持 views 视图目录
    • 默认将 Pug 作为模版引擎
      1. npm i koa-generator -g
      2. koa2 helloworld # 创建项目骨架
      image.png
      1. cd helloworld
      2. npm i
      3. npm start
      4. tree . -L 2 # 查看生成的目录结构
      “debug”: “^4.1.1”,:根据 Debug 环境变量输出调试日志
      “koa”: “^2.7.0”,核心模块,用于提供中间件机制
      “koa-bodyparser”: “^4.2.1”,用于解析和处理 body,主要针对 Post 类的请求
      “koa-convert”: “^1.2.0”,将 Koa1 中间件转换为 Koa2 可兼容的中间件
      “koa-json”: “^2.0.2” 提供对 JSON 的更好支持,
      “koa-logger”: “^3.2.0”,开发阶段使用的日志模块
      “koa-onerror”: “^4.1.0”,异常捕获模块
      “koa-router”: “^7.4.0”,路由模块
      “koa-static”: “^5.0.0”HTTP 静态服务模块,
      “koa-views”: “^6.2.0”,视图配置模块
      “pug”: “^2.0.3”用于视图渲染,是非常流行的极简模式的模版引擎

核心文件 app.js

  1. // middlewares
  2. app.use(bodyparser({
  3. enableTypes:['json', 'form', 'text']
  4. })) // 解析 POST 类 HTTP 动词的 body 内容,加上 bodyparser 后就可以处理所有请求了
  5. app.use(json()) // 更好地支持JSON
  6. app.use(logger()) // 开发阶段日志
  7. app.use(require('koa-static')(__dirname + '/public')) // 提供 HTTP 静态托管服务
  8. app.use(views(__dirname + '/views', {
  9. extension: 'pug' // 视图渲染,支持模版引擎
  10. }))
  1. // 自定义 logger 中间件
  2. app.use(async (ctx, next) => {
  3. const start = new Date()
  4. await next()
  5. const ms = new Date() - start
  6. console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
  7. })

routes

路由就是根据特定请求路径进行特定处理的中间件,是比较简单、初级的解偶方式。

  1. // router/index.js
  2. const router = require('koa-router')()
  3. // 视图渲染
  4. router.get('/', async (ctx, next) => {
  5. // 通过中间件在 ctx 中绑定我们要使用的功能,这里添加了 koa-views 中间件
  6. await ctx.render('index', {
  7. title: 'Hello Koa 2!'
  8. })
  9. })
  10. // 字符串
  11. router.get('/string', async (ctx, next) => {
  12. ctx.body = 'koa2 string'
  13. })
  14. // JSON API
  15. router.get('/json', async (ctx, next) => {
  16. ctx.body = {
  17. title: 'koa2 json'
  18. }
  19. })
  20. module.exports = router

app.js 里进行挂载:

  1. // routes
  2. app.use(index.routes(), index.allowedMethods())
  3. app.use(users.routes(), users.allowedMethods())

path-to-regexp 模块就是路由实现的核心。

public

koa-static 是一个用于文件托管的中间件,是基于 koa-send 的高级封装。功能类似于 nginx。

  • 纯 API 项目,不需要 public 目录
  • 纯前后端分离项目,后端不需要 public 目录,前端需要
  • 需要 public 目录的项目,但会将 public 目录里的内容分发到 CDN 上

views

模板引擎采取了一种复用思想,通过定义模板,在使用时和数据一起编译,生成 HTML 页面,以便浏览器渲染。
koa-views 依赖 consolidate.js(提供缓存)以解决模板编译耗时的情况。
ctx.render 就是用于渲染模版的方法:

  • 通过文件读取 index.pug 模板
  • 使用 Pug 模板引擎编译器将数据和模板内容编译为 HTML 字符串
  • Content-Type 设置为 text/html
  • statusCode 状态码设置为200
  • 通过 http 模块底层的 res.writeres.end 方法将 HTML 字符串写入浏览器

consolidate.js 支持3种模板引擎:

  • Pug:无参数指定模板引擎的时候默认使用
  • EJS:通过-e,-ejs来支持
  • Numjucks: 通过 -n, —nunjucks 来支持

如:

  1. koa2 -e helloworld-ejs

如果需要使用其他模版引擎,如react,则:

  • 安装对应的模板引擎模块:npm install —save react
  • 修改 app.js 里与 koa-views 相关的配置,将 extension 设置为 react ```javascript app.use(views(__dirname + ‘/views’, { extension: ‘react’ }))

```

  • 参考 react 组件的写法来修改 views 目录里的文件