Koa应用
@ 姜波 | 星期六,九月 14 日,2019 年 | 3 分钟阅读 | 更新于 星期六,九月 14 日,2019 年

Koa应用

安装

npm init -y
npm install -S koa

index.js
const Koa = require('koa')
const app = new Koa()

app.use(async ctx => {
  ctx.body = 'Hello World'
})

app.listen(3000)

request常用属性

ctx.request.url//ctx.url
ctx.request.method//ctx.method
ctx.request.headers//ctx.headers

response常用属性

ctx.response.set//ctx.set
ctx.response.status//ctx.status
ctx.response.body//ctx.body

router

npm install -S koa-router

index.js
const Router = require('koa-router')
const router = new Router()

router.get('/', ctx => {
  ctx.body = 'Hello World'
})

app.use(router.routes())
.use(router.allowedMethods())

middleware

middleware.js
const Koa = require('koa')
const app = new Koa()

const middleware1 = function async(ctx,next){
  next()
}
const middleware2 = function async(ctx,next){
  next()
}
const middleware3 = function async(ctx,next){
  next()
}

app.use(middleware1)
app.use(middleware2)
app.use(middleware3)

app.listen(3000)

async、await

index.js
router.get('/async', async (ctx) => {
  let result = await new Promise((resolve) => {
    setTimeout(function(){
      resolve('Hello World 2s later')
    },2000)
  })
  ctx.body = result
})

第三方中间件

  • 处理请求体 koa-bodyparser

    • 非GET请求,比如说post请求 ,包括表单提交的form内的数据,都能轻松获取
    • ctx.request.body 获取form中的数据
  • 处理路由 koa-router

    • 获取查询字符串 ctx.query
    • 获取/xxx/:id ctx.params.id
    • koa-bodyparser是解析请求体数据的,koa-router中可以通过ctx.query||ctx.params获取url上的参数
  • 处理静态资源 koa-static

  • 渲染页面 koa-art-template

    • koa与视图通信的对象 ctx.state
  • session中间件 koa_session

    • sign:true 会生成一个关于cookie数据保障不被修改的签名,如果数据改了,但是签名还是之前的状态,就说明数据不安全
    • app.keys 必须要,内部通过该值进行标识或者说计算
    • 操作session ctx.session.xxx

常用中间件

npm install -S koa-router koa-body @koa/cors

index.js
const cors = require('@koa/cors')
const koaBody = require('koa-body')

router.post('/post', async (ctx) => {
  let { body } = ctx.request
  ctx.body={
    ...body
  }
})

app.use(koaBody())
app.use(cors())
app.use(router.routes())
.use(router.allowedMethods())

路由前缀

router.prefix('/api')

获取get请求中的params

router.get('/', ctx => {
  const params = ctx.request.query
})

koa-json

npm install -S koa-json

index.js
const json = require('koa-json')

app.use(koaBody())
app.use(cors())
app.use(json({ pretty:false, param:'pretty'}))
app.use(router.routes())
.use(router.allowedMethods())

koa-combine-routers

npm install koa-combine-routers -S

api/a.js
module.exports = function(ctx){
	ctx.body = {
    'message' : 'hello from a'
  }
}

api/b.js
module.exports = function(ctx){
	ctx.body = {
    'message' : 'hello from b'
  }
}

routes/aRouter.js
const Router = require('koa-router')
const a = require('../api/a')
const router = new Router()

router.get('/a',a)

module.exports = router

routes/bRouter.js
const Router = require('koa-router')
const b = require('../api/b')
const router = new Router()

router.get('/b',b)

module.exports = router

routes/routes.js
const combineRoutes = require('koa-combine-routers')

const aRoutes = require('./aRouter')
const bRoutes = require('./bRouter')

module.exports = combineRoutes(
	aRoutes,bRoutes
)

index.js
const Koa = require('koa')
const app = new Koa()
const router = require('./routes/routes')

app.use(router())

app.listen(3000)

koa安全header处理

npm install koa-helmet -S

index.js
const helmet = require('koa-helmet')

app.use(helmet())
app.use(router())

app.listen(3000)

静态资源服务

npm install koa-static -S

index.js
const path = require('path')
const statics = require('koa-static')

app.use(helmet())
app.use(statics(path.join(__dirname,'./public')))
app.use(router())

app.listen(3000)

koa开发热加载

npm install nodemon -D
npx nodemon index.js

热加载和es6的webpack配置

安装

npm install webpack webpack-cli -D
npm install -D clean-webpack-plugin webpack-node-externals @babel/core @babel/node @babel/preset-env babel-loader cross-env

webpack.config.js

const path = require('path')
const nodeExternals = require('webpack-node-externals')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')

const webpackconfig = {
  target:'node',
  mode:'development',
  entry:{
 		server:path.join(__dirname,'src/index.js')
  },
  output:{
    filename:'[name].bundle.js'
    path:path.join(__dirname,'./dist')
  },
  devtool:'eval-source-map',
  module:{
    rules:[
      {
        test:/\.(js|jsx)$/,
        use:{
          loader:'babel-loader'
        },
        exclude:[path.join(__dirname,'/node_modules')]
      }
    ]
  },
  externals:[nodeExternals()],
  plugins:[
    new CleanWebpackPlugin()
  ],
  node:{
    console:true,
    global:true,
    process:true,
		Buffer:true,
    __filename:true,
    __dirname:true,
    setImmediate:true,
    path:true
  }
}
module.exports = webpackconfig

.babelrc

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets":{
          "node":"current"
        }
      }
    ]
  ]
}

es6语法支持

import koa from 'koa'
import path from 'path'
import helmet from 'koa-helmet'
import statics from 'koa-static'
import router from './routes/routes'
import koaBody from 'koa-body'
import jsonutil from 'koa-json'
import cors from '@koa/cors'

npx babel-node index.js
npx nodemon --exec babel-node index.js

调试webpack

debugger
const webpackconfig = {}
console.log(webpackconfig)

npx node --inspect-brk ./node_modules/.bin/webpack --inline --progress

chrome://inspect/#devices

npm 包检查更新

npm install -g npm-check-updates
ncu // 检查新版本
ncu -u //更新

中间件整合

npm install koa-compose -S

import compose from 'koa-compose'

const middleware = compose([
  koaBody(),
  statics(path.join(__dirname,'./public')),
  cors(),
  jsonutil({ pretty:false, param:'pretty'}),
  helmet()
])

app.use(middleware)
app.use(router)

webpack开发、生产环境配置

webpack.config.base.js

const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')

const webpackConfig = {
  target:'node',
  entry:{
 		server:path.join(__dirname,'src/index.js')
  },
  output:{
    filename:'[name].bundle.js'
    path:path.join(__dirname,'./dist')
  },
  module:{
    rules:[
      {
        test:/\.(js|jsx)$/,
        use:{
          loader:'babel-loader'
        },
        exclude:[path.join(__dirname,'/node_modules')]
      }
    ]
  },
  externals:[nodeExternals()],
  plugins:[
    new CleanWebpackPlugin(),
    new webpack.DefinePlugin({
      process.env:{
      	NODE_ENV:(process.env.NODE_ENV === 'production'||process.env.NODE_ENV === 'prod')?"'production'":"'development'"
   		}
    })
  ],
  node:{
    console:true,
    global:true,
    process:true,
		Buffer:true,
    __filename:true,
    __dirname:true,
    setImmediate:true,
    path:true
  }
}
module.exports = webpackConfig

webpack.config.dev.js

npm install webpack-merge -D

const webpackMerge = require('webpack-merge')

const baseWebpackConfig = require('./webpack.config.base')
const webpackConfig = webpackMerge(baseWebpackConfig,{
  mode:'development',
  devtool:'eval-source-map',
  stats:{
    children:false
  }
})

module.exports = webpackConfig

webpack.config.prod.js

npm install terser-webpack-plugin -D

const webpackMerge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.config.base')
const terserWebpackPlugin= require('terser-webpack-plugin')

const webpackConfig = webpackMerge(baseWebpackConfig,{
  mode:'production',
  devtool:'eval-source-map',
  stats:{
    children:false,
    warnings:false
  },
  optimization: {
    minimizer: [
      new terserWebpackPlugin({
        terserOptions:{
          warnings:false,
          compress:{
            warnings:false,
            // 是否注释掉console
            drop_console:false,
            dead_code:true,
            drop_debugger:true
          },
          output:{
            comments:false,
            beautify:false
          },
          mangle:true
        },
        parallel:true,
        sourceMap:false
      })
    ],
    splitChunks:{
      casheGroups:{
        commons:{
          name:'commons',
          chunks:'initial',
          minChunks:3,
          enforce:true
        }
      }
    }
  },
})
module.exports = webpackConfig

打包优化

cross-env多平台支持

npm install -D cross-env

{
	"scripts":{
    "build":"cross-env NODE_ENV=prod webpack --config config/webpack.config.prod.js"
  }
}

开发环境脚本

npm install rimraf -D
{
	"scripts":{
   	"dev":"cross-env NODE_ENV=dev nodemon --exec babel-node --inspect index.js",
    "clean":"rimraf dist"
  }
}

开发环境压缩

npm install koa-compress -S

index.js
import compress from 'koa-compress'

const isDevMode = process.env.NODE_ENV === "production" ? false:true

if(isDevMode){
   app.use(compress())
}

公众号

Image text

QQ

Image text

微信

Image text

微信打赏

Image text

社交链接