koa2

120 阅读3分钟

koa2 开发环境

  • 配置eslint,以及 pre-commit
  • inspet 调试
  • 404页和错误页

配置eslint

npm install eslint babel-eslint --save

.eslintrc.json

{
    "parser": "babel-eslint",
    "env": {
        "es6": true,
        "commonjs": true,
        "node": true
    },
    "rules": {
        "indent": ["error", 2],
        "quotes": [
            "error",
            "single",
            {
              "allowTemplateLiterals": true
            }
        ],
        "semi": [
            "error",
            "never"
        ]
    }
}

.eslintignore

node_modules
test
src/public

阻止eslint校验没通过,就提交代码到git仓库,安装pre-commit

npm install pre-commit --save-dev

修改package.json文件

inspet 调试

"dev": "cross-env NODE_ENV=dev ./node_modules/.bin/nodemon --inspect=9299 bin/www"

jwt

jwt 是什么

jwt - json web token

用户认证成功之后,serve 端返回一个加密的token给客户端

客户端后续每次请求都带token,以示当前的用户身份

安装 koa-jwt,可以解析jwt的加密解密

安装jsonwebtoken,加密工具

jwt vs session

  • 为了解决:登录&存储登录用户的信息
  • jwt用户信息加密存储在客户端,不依赖cookie,可跨域
  • session用户信息存储在服务端,依赖cookie,默认不可跨域

jwt更适合于服务节点较多,跨越比较多的系统,session更适合于统一的web服务,server要严格管理用户信息

redis

内存数据库 (mysql是硬盘数据库)

  • 安装:
  • 启动:redis-server,redis-cli
  • 设置值:set name 'cc'
  • 取值:get name
  • 查询所有的值:keys *
  • 退出:exit

node 操作 redis

安装:npm install redis --save

/**
 * @description 连接 redis 的方法 get set
 */

const redis = require('redis')
const { REDIS_CONF } = require('../conf/db')

// 创建客户端
const redisClient = redis.createClient({
6379,127.0.0.1
})
redisClient.on('error', err => {
  console.error('redis error', err)
})

/**
 * redis set
 * @param {string} key 键
 * @param {string} val 值
 * @param {number} timeout 过期时间,单位 s
 */
function set(key, val, timeout = 60 * 60) {
  if (typeof val === 'object') {
    val = JSON.stringify(val)
  }
  redisClient.set(key, val)
  redisClient.expire(key, timeout)
}

/**
 * redis get
 * @param {string} key 键
 */
function get(key) {
  const promise = new Promise((resolve, reject) => {
    redisClient.get(key, (err, val) => {
      if (err) {
        reject(err)
        return
      }
      if (val == null) {
        resolve(null)
        return
      }

      try {
        resolve(
          JSON.parse(val)
        )
      } catch (ex) {
        resolve(val)
      }
    })
  })
  return promise
}

module.exports = {
  set,
  get
}

为何session适合用redis

  • session 访问频繁,对性能要求极高
  • session 可不考虑断电丢失数据的问题(内存的硬伤)
  • session 数据量不会太大

为何网站数据不适合用redis

  • 操作频率不是太高(相比于session操作)
  • 断电不能丢失,必须保留
  • 数据量太大,内存成本太高

koa2中如何操作redis,session,cookie

npm i koa-redis koa-generic-session --save

const session = require('koa-generic-session')
const redisStore = require('koa-redis')
// session 配置
app.keys = [SESSION_SECRET_KEY]
app.use(session({
  key: 'weibo.sid', // cookie name 默认是 `koa.sid`
  prefix: 'weibo:sess:', // redis key 的前缀,默认是 `koa:sess:`
  cookie: {
    path: '/',
    httpOnly: true, // 只能在server端修改,客户端无权修改
    maxAge: 24 * 60 * 60 * 1000  // 单位 ms,过期时间
  },
  store: redisStore({ // 将session数据存到redis
    all: `${REDIS_CONF.host}:${REDIS_CONF.port}`
  })
}))

jest 单元测试

使用jest

  • 必须是 .test.js 结尾的文件
  • 常用的断言
  • 测试 http 接口
  1. 安装
npm install jest --save-dev
  1. 修改 package.json 文件
"scripts": {
	"test": "cross-env NODE_ENV=test jest --runInBand --forceExit --colors"
}
  1. demo
function sum (a, b) {
  return a + b
}
test('10+20===30', () => {
  const res = sum(10,20)
  expect(res).toBe(30) // 判断值是否相等
})
test('10+20!==40', () => {
  const res = sum(10,20)
  expect(res).not.toBe(40)
})
  1. 测试 http server
npm install supertest --save-dev

server.js

const request = require('supertest')
const server = require('../src/app').callback()
module.exports = request(server)

json.test.js

const server = require('./server')

test('json 接口返回格式正确', async() => {
  const res = await server.get('/json')
  expect(res.body).toEqual({ // 判断对象是否相等
    title: 'koa2 json'
  })
  expect(res.body.title).toBe('koa2 json')
})
test('测试 post 请求', async() => {
  const res = await server.post('/login').send({
  	userName: '',
    password: ''
})
  expect(res.body).toEqual({ // 判断对象是否相等
    success: true
  })
})