首页 > 其他 > 详细

基于koa2.x搭建node中间层(一):项目搭建

时间:2021-05-20 15:11:21      阅读:25      评论:0      收藏:0      [点我收藏+]

基于Koa2.x开发node中间层

一. 安装

新建一个开发文件夹 比如 node-demo并初始化

npm init -y

pm2是一个进程管理工具,需要全局安装

npm i pm2 -g

nodemon是一个node文件启动工具,可以自动检测到目录中的文件更改,通过重启应用程序来调试基于node.js的应用程序

npm install nodemon --save-dev

安装koa框架

npm i koa --save

package.json"script"命令下加入以下命令:

"dev":"nodemon app.js",
"start":"pm2 start app.js --name your-project-name --watch"

注:npm run dev用作开发调试,npm run start用作测试或生产启动

项目根目录下新建app.js,用于实例化Koa,启动一个node服务器,内容如下

const Koa = require("koa");
const app = new Koa();
const PORT = 3000;
app.listen(PORT,()=>{
console.log(`App is running at http://127.0.0.1:${PORT}`)
})

二. 路由

router其实也是一种中间件

考虑到一个中间层可能对接不同的前端项目,因此路由设置应划分模块

例如,中间层有两个模块module_1和module_2,这个时候再写在app.js中难免混乱,最好以中间件的形式剥离出来

在根目录下创建router.js,内容如下

const KoaRouter = require("koa-router");
const router = new KoaRouter();
module.exports = app => {
router.use("/test",async ctx=>{
ctx.body = ‘test success‘;
})
app.use(router.routes()).use(router.allowedMethods());
}

在app.js中

const router = require("./router");
...
router(app);
app.listen...

三. 多环境配置

为了区分开发,测试和生产环境,需要进行多环境配置

安装依赖

npm install config --save

在项目根目录下建立config文件夹

新建default.json,staging.json,production.json文件
例如在default.json中

{
"port":"3000"
}

在staging.json中

{
"port":"3001"
},

在production.json中

{
"port":"3002"
}

在app.js中引入

const Koa = require("koa");
const config = require("config");
const app = new Koa();
---   const PORT = 3000;
+++ const PORT = config.get("port")
app.listen(PORT,()=>{
console.log(`App is running at http://127.0.0.1:${PORT}`)
})

其他需要多环境配置的变量引入方法类似
同时设置package.json中的scripts:

"staging":"export NODE_ENV=staging&&npm start",
"production":"export NODE_ENV=production&&npm start"

四. 中间件

koa最大的特点就是独特的中间件流程控制,是一个典型的洋葱圈模型.koa2在node7.6之后可以直接使用async/await使用中间件.下图很清晰的表明了一个请求是如何经过中间件最后生成响应的,这种模式开发和使用中间件都是非常方便的.

四(1)处理Error的中间件

四(2)处理cookie的中间件

四(3)处理json格式的中间件

四(4)处理post参数和文件上传的中间件

四(5)处理静态文件的中间件

四(6)处理跨域的中间件

四(7)处理日志的中间件

五. 多模块

一个中间层对应的可能不止一个前端项目,为了多人开发,不同模块的controller,servicer,router和通信的配置肯定不能混成一锅粥,这里的解决方案是以路由作为模块划分的标识.

例如有两个模块module_a和module_b,我们在根目录下新建两个文件夹module_a和module_b.我们以module_a为例,在module_a下新建router.js,内容如下:

const router = require("koa-router")();
router.get("/test",async (ctx)=>{
ctx.body = "module_a test";
})
module.exports = router.routes();

同时,在根目录下的router.js文件夹下要注册module_a的路由

...
module.exports = app => {
router.use("/module_a",require("./module_a/router"))
...
router.get("/test",async ctx=>{

六. 日志

运行在服务器的程序需要日志来记录程序的运行状况,这里推荐使用log4js

安装依赖

npm i log4js --save

最好把log设置成中间件

在middleware文件夹下新建logger文件夹

分别新建index.js,logger.js,access.js文件,

index.js负责封装logger中间件,logger.js主要写入一些logger的配置,access.js主要配置日志的访问信息

在logger.js文件中(注意不同环境进行不同的日志级别配置

{
logInfo:{
env:"dev",
level:"debug",
dir:"logs"
}
}

)

const log4js = require(‘log4js‘);
const methods = ["trace","debug","info","warn","error","fatal","mark"];
const logInfo = require("config").get("logInfo");
const access = require("./access");
module.exports = () =>{
const {env,level,dir} = logInfo;
const contextLogger = {};
const appenders = {};
appenders.nodeLog = {
    type:"dateFile",
    filename:`${dir}/task`,
    pattern:`-yyyy-MM-dd.log`,
    alwaysIncludePattern:true
  };
if(env === ‘dev‘){
appenders.out = {
      type:"console"
    }
  }
let config = {
appenders,
    categories:{
      default:{
        appenders:Object.keys(appenders),
level,
      }
    }
  }
const logger = log4js.getLogger(‘nodeLog‘);
log4js.configure(config);
return async (ctx,next) => {
const commonInfo = {};
const start = Date.now();
methods.forEach(method=>{
contextLogger[method] = message => {
logger[method](access(ctx,message,commonInfo))
      }
    })
ctx.log = contextLogger;
await next();
const end = Date.now();
const responseTime = end - start;
logger.info(access(ctx,{
      responseTime:`响应时间为${responseTime/1000}s`
    },commonInfo))
  }
}

在access.js文件中

module.exports = (ctx,message,commonInfo) => {
const { method,url,host,headers } = ctx.request;
const client = {
method,url,host,message,referer:headers[‘referer‘],userAgent:headers[‘user-agent‘]
  }
return JSON.stringify(Object.assign(commonInfo,client))
}

在index.js文件中

const logger = require("./logger");
module.exports = () => {
return logger();
}

随后在middleware的index.js中引入

const logger = require("./logger");
...
app.use(logger())
...

七. 异常处理

异常处理以中间件的方式,根据洋葱圈模型,中间件应该置于最外层的await next()之后捕获,这样能确保捕获到所有异常

在middleware下新建handleError.js,并设置如下

module.exports = async (ctx,next)=>{
await next().catch(err=>{
// 在日志系统中写入这个错误
ctx.log.error(err.message)
//保证能正常返回给前端,注意:这里可能需要判断401或403,根据业务类型,下面的内容也不同
ctx.status = 200;
ctx.body = {
      code:-1,
      success:false,
      data:null,
      msg:"中间层异常",
    }
  })
}

在middleware的index.js下注册这个中间件(放到中间件顺序的第一位)

const handleError = require("./handleError");
....
app.use(handleError)
....

基于koa2.x搭建node中间层(一):项目搭建

原文:https://www.cnblogs.com/cheeliu/p/14789078.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!