Egg企业级实战(一)- 框架搭建

2,872 阅读5分钟

本文按照完成的开发流程从实例的角度,一步步地搭建出一个开箱即用的Egg.js 应用,让我们开始吧!

完整项目地址:gitee.com/koukaile/eg…

本系列文章目录

01.安装egg.js

环境准备

操作系统:支持 macOS,Linux,Windows
运行环境:建议选择 LTS 版本,最低要求 8.x。

快速初始化

我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目(npm >=6.1.0):

$ mkdir egg-example && cd egg-example    
$ npm init egg --type=simple  
$ npm i  

启动项目:

$ npm run dev   
$ open http://localhost:7001  

02.目录构建

这里简单进行项目的架构展示

egg-project
├── package.json
├── app.js (用于自定义启动时的初始化工作)
├── agent.js (用于自定义启动时的初始化工作)
├── app
|   ├── router.js(用于配置 URL 路由规则)
|   ├── contract(用于配置swagger)
│       ├── type.js (默认接口类型配置)
│       ├── contract.js (请求示例数据配置)
│   ├── controller(用于解析用户的输入,处理后返回相应的结果)
│   |   └── home.js
│   ├── service (用于编写业务逻辑层)
│   |   └── user.js
│   ├── middleware (用于编写中间件)
│   |   └── response_time.js
│   ├── schedule (用于定时任务)
│   |   └── my_task.js
│   ├── public (放置静态资源)
│   |   └── reset.css
│   ├── view (用于放置模板文件,由模板插件约定)
│   |   └── home.tpl
│   ├── model (用于放置领域模型,由领域类相关插件约定)
│   └── extend (用于框架的扩展)
│       ├── helper.js (可选)
│       ├── request.js (可选)
│       ├── response.js (可选)
│       ├── context.js (可选)
│       ├── application.js (可选)
│       └── agent.js (可选)
├── logs(用于存储日志文件)
├── config(用于编写配置文件)
|   ├── plugin.js(用于配置需要加载的插件)
|   ├── config.default.js
│   ├── config.production.js
|   ├── config.test.js 
|   ├── config.local.js 
|   └── config.preview.js 
└── test(用于单元测试)
|    ├── middleware
|    |   └── response_time.test.js
|    └── controller
|        └── home.test.js
└── database(sequelize数据库)

03.数据库连接

建立数据库

  • 启动数据库
  • 建立数据库(本文使用phpstudy建立)
  • 连接数据库(本文使用Navicat)

egg 中配置数据库

1.安装对应的插件 egg-mysql :

$ npm i --save egg-mysql

2.开启插件:

//地址 -> config/plugin.js
exports.mysql = {
  enable: true,
  package: 'egg-mysql',
};

3.单数据源

如果我们的应用只需要访问一个 MySQL 数据库实例,可以如下配置:

  //地址 ->  /config/config.default.js
  // 数据库配置
  config.mysql = {
    // 单数据库信息配置
    client: {
      // host
      host: 'localhost',
      // 端口号
      port: '3306',
      // 用户名
      user: '',
      // 密码
      password: '',
      // 数据库名
      database: '',
    },
    // 是否加载到 app 上,默认开启
    app: true,
    // 是否加载到 agent 上,默认关闭
    agent: false,
  };

04.swagger接口文档配置

官方使用文档:www.npmjs.com/package/egg…

安装 egg-swagger-doc

npm i egg-swagger-doc --save // 自动生成接口描述配置

配置 egg-swagger-doc

//地址 ->  config/config.default.js
exports.swaggerdoc = {
  dirScanner: './app/controller', // 配置自动扫描的控制器路径
  // 接口文档的标题,描述或其它
  apiInfo: {
      title: 'Render',  // 接口文档的标题
      description: 'swagger-ui for Render document.',   // 接口文档描述
      version: '1.0.0',   // 接口文档版本
  },
  schemes: ['http', 'https'], // 配置支持的协议
  consumes: ['application/json'], // 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html
  produces: ['application/json'], // 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
  securityDefinitions: {  // 配置接口安全授权方式
      // apikey: {
      //   type: 'apiKey',
      //   name: 'clientkey',
      //   in: 'header',
      // },
      // oauth2: {
      //   type: 'oauth2',
      //   tokenUrl: 'http://petstore.swagger.io/oauth/dialog',
      //   flow: 'password',
      //   scopes: {
      //     'write:access_token': 'write access_token',
      //     'read:access_token': 'read access_token',
      //   },
      // },
  },
  enableSecurity: false,  // 是否启用授权,默认 false(不启用)
  // enableValidate: true,    // 是否启用参数校验,默认 true(启用)
  routerMap: true,    // 是否启用自动生成路由,默认 true (启用)
  enable: true,   // 默认 true (启用)
};

配置swagger

//地址 -> config/plugin.js
// 配置 egg-swagger-doc 插件信息
module.exports.swaggerdoc = {
  enable: true,   // 启用 swagger-ui 默认启用
  package: 'egg-swagger-doc', // 指定 第三方插件 包名称
};

创建业务逻辑层

config/plugin.js app/service/home.js
const { Service } = require('egg'); //拿到 egg 对象的Service基类

所有的业务逻辑都在业务层设置完成,在控制层只是调用相应的方法即可

'use strict'

const Service = require('egg').Service;

class HomeService extends Service{
//测试数据
async test(){
  const result = await this.app.mysql.query('select * from test', '')
  return JSON.stringify({
     code:1,
     message:'success',
     data:result
  })
}
}

module.exports = HomeService

创建控制器(api接口)

//地址 -> app/controller/home.js
const { Controller } = require('egg'); //解构出 Controller 基类

app/controller/home.js

'use strict'

/**
* @Controller
**/

const Controller = require('egg').Controller;

class HomeController extends Controller {
async test() {
 /**
 * @summary 测试数据库连接
 * @description 测试swagger
 * @router post /home/test
 * @request body string test 配置请求携带示例数据
 * @Request header string token eg:write your params at here
 * @response 200 JsonResult 操作结果
 */
 const { ctx } = this;
 ctx.body = await this.service.home.test()
}
}

module.exports = HomeController;

配置接口请求时的示例数据

//地址 -> app/contract/contract.js
/* 配置swagger请求示例数据 */

module.exports = {
//test
test: {
 name: { type: 'string', required: true, enum: 'test' },
},
};

配置接口返回值的约束(必须配置)

//地址 -> app/contract/type.js
module.exports = {
     // 默认接口类型
     JsonResult: { //@response 200 JsonResult 操作结果,名字与相应结果对应
         success: { type: 'boolean' },    // 结果
         results: { type: 'string' }     // 服务器返回的数据
     },
}

配置路由router.js

//地址 -> app/router.js
'use strict';

/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const { router, controller } = app;
// 重定向到swagger
router.redirect('/', '/swagger-ui.html' , 302);
// 接口路由
router.get('/home/test', controller.home.test);
};

测试swagger

浏览器输入 http://127.0.0.1:7001/

1611903686384_E3CFC229-619B-4fa7-AE9D-CC23D6D84EBD.png 如上图所示,就大功告成啦~

05.跨域问题

在前后端分离对接时,跨域是最常见的问题,这里对egg处理跨域进行处理

1.下载 egg-cors 包

npm i egg-cors --save

2.在plugin.js中设置开启cors

exports.cors = {
  enable: true,
  package: 'egg-cors',
};

3.在config.default.js中配置

  // 跨域配置
  config.security = {
    csrf: {
      enable: false,
      ignoreJSON: true,
    },
    domainWhiteList: ['http://127.0.0.1'],
  };
  config.cors = {
    origin: '*',
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
  };

06.配置打印日志

打印日志配置

// /config/config.local.js
'use strict';

module.exports = () => {

  const config = exports = {};

  config.logger = {
    dir: '../logs/local', // 打印目录重定向
    outputJSON: true, // json格式输出
  };

  return {
    ...config,
  };
};

日志类型

首先eggjs产生的日志有三类。

  • 业务日志 common-error.log
    egg-agent.log
    egg-web.log
    ${appInfo.name}-web.log

  • 定时任务日志
    egg-schedule.log

  • 框架启动日志
    master-stderr.log
    master-stdout.log

  • 日志打印
    logger.debug()
    logger.info()
    logger.warn()
    logger.error()

07.环境配置

一个项目完整的生命周期通常包括:

  • 本地环境
  • 测试环境
  • 准生产环境(灰度环境)
  • 生产环境(线上环境)

egg中配置(package.json)

"scripts": {
    "start": "egg-scripts start --daemon --title=egg-server-EggZoneFrame",
    "stop": "egg-scripts stop --title=egg-server-EggZoneFrame",
    "dev": "egg-bin dev --env=local",//本地环境
    "dev-test": "egg-bin dev --env=test",//测试环境
    "dev-preview": "egg-bin dev --env=preview",//准生产环境
    "dev-production": "egg-bin dev --env=production",//生产环境
    "debug": "egg-bin debug",
    "test": "npm run lint -- --fix && npm run test-local",
    "cov": "egg-bin cov",
    "lint": "eslint .",
    "ci": "npm run lint && npm run cov",
    "autod": "autod"
  },

--env=环境名 配置当前环境

 npm run 环境参数  启动相对应的环境,此处和vue的环境配置类似
 npm run dev  //启动本地环境
 npm run dev-test  //启动测试环境
 npm run dev-preview  //启动准生产环境
 npm run dev-production  //启动生产环境

config 配置

通常不同环境需配置不同的数据库地址,端口地址,日志打印目录等...

  • config.default.js 默认配置
  • config.local.js 本地环境配置
  • config.test.js 测试环境配置
  • config.preview.js 准生产环境配置
  • config.production.js 生产环境配置

08.总结

到此为止,一套node服务已经搭建完成~

总结如下:

  • 安装

  • 构建开发目录

  • 数据库连接

  • 配置swagger

  • 处理前后端联调跨域

  • 打印日志配置

  • 环境配置 如果上面的都搭建完成了,那么node框架就已经搭建成功啦!快去你的前端接口中对接吧~
    看完觉得不错的话,就给点个赞吧~