eggjs

eggjs

eggjs官网

项目搭建

  1. 创建项目

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

    该示例中类库版本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    { 
    "dependencies": {
    "egg": "^2.15.1",
    "egg-scripts": "^2.11.0"
    },
    "devDependencies": {
    "autod": "^3.0.1",
    "autod-egg": "^1.1.0",
    "egg-bin": "^4.11.0",
    "egg-ci": "^1.11.0",
    "egg-mock": "^3.21.0",
    "eslint": "^5.13.0",
    "eslint-config-egg": "^7.1.0"
    },
    "engines": {
    "node": ">=10.0.0"
    },
    }
  2. 启动项目

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

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
egg-project
├── package.json
├── app.js (可选)
├── agent.js (可选)
├── app
| ├── router.js
│ ├── controller
│ | └── home.js
│ ├── service (可选)
│ | └── user.js
│ ├── middleware (可选)
│ | └── response_time.js
│ ├── schedule (可选)
│ | └── my_task.js
│ ├── public (可选)
│ | └── reset.css
│ ├── view (可选)
│ | └── home.tpl
│ └── extend (可选)
│ ├── helper.js (可选)
│ ├── request.js (可选)
│ ├── response.js (可选)
│ ├── context.js (可选)
│ ├── application.js (可选)
│ └── agent.js (可选)
├── config
| ├── plugin.js
| ├── config.default.js
│ ├── config.prod.js
| ├── config.test.js (可选)
| ├── config.local.js (可选)
| └── config.unittest.js (可选)
└── test
├── middleware
| └── response_time.test.js
└── controller
└── home.test.js

如上,由框架约定的目录:

  • app/router.js 用于配置 URL 路由规则,具体参见 Router
  • app/controller/** 用于解析用户的输入,处理后返回相应的结果,具体参见 Controller
  • app/service/** 用于编写业务逻辑层,可选,建议使用,具体参见 Service
  • app/middleware/** 用于编写中间件,可选,具体参见 Middleware
  • app/public/** 用于放置静态资源,可选,具体参见内置插件 egg-static
  • app/extend/** 用于框架的扩展,可选,具体参见框架扩展
  • config/config.{env}.js 用于编写配置文件,具体参见配置
  • config/plugin.js 用于配置需要加载的插件,具体参见插件
  • test/** 用于单元测试,具体参见单元测试
  • app.jsagent.js 用于自定义启动时的初始化工作,可选,具体参见启动自定义。关于agent.js的作用参见Agent机制

由内置插件约定的目录:

  • app/public/** 用于放置静态资源,可选,具体参见内置插件 egg-static
  • app/schedule/** 用于定时任务,可选,具体参见定时任务

若需自定义自己的目录规范,参见 Loader API

  • app/view/** 用于放置模板文件,可选,由模板插件约定,具体参见模板渲染
  • app/model/** 用于放置领域模型,可选,由领域类相关插件约定,如 egg-sequelize

使用 eggjs时需要重点注意的两个目录,app (工作目录,业务逻辑)和config(项目配置)

eggjs使用

  1. 路由 Router :app/router.js 匹配请求URL与控制器Controller的对应关系。
  2. 控制器 Controller:在 app/controller 目录下可以根据 请求 作出不同的响应。
  3. 服务 Service:在复杂业务场景下用于做业务逻辑封装的一个抽象层,提供这个抽象有以下几个好处:
    1. 保持 Controller 中的逻辑更加简洁。
    2. 保持业务逻辑的独立性,抽象出来的 Service 可以被多个 Controller 重复调用。
    3. 将逻辑和展现分离,更容易编写测试用例,测试用例的编写具体可以查看这里。

post/get

在路由配置文件app\router.js 中可以通过 router 对象设置接收客户端的get或post请求。

1
2
3
4
5
6
7
// app\router.js

module.exports = app => {
const { router, controller } = app;
router.get('/', controller.home.index);
router.post('/pd',koaBody,controller.home.postdemo);
};
  1. router.get() router.post() 只能接收对应的请求方式。
  2. get()/post()中两个参数第一个参数为 url路径规则, 第二个参数 controller.home.index 则对应 controller/home.jsindex 方法。

当路由规则匹配到在 controller 中所对应的方法后,就可以在这个方法中根据请求者的参数作出相应的响应。

  1. get 请求时获取参数

    1
    2
    3
    const { ctx } = this;
    //获取 get 请求参数
    console.log(ctx.query)
  2. post请求时 需要通过 中间件 koa-body 否则不能正常获取到post请求参数,可参考后面 koa-body 中间件配置

    1
    2
    3
    const { ctx } = this;
    // 获取post请求的 请求参数
    const param = ctx.request.body

在 controller 中需要返回必须返回数据给调用者,否则程序将出错 返回数据 可以通过 ctx.body

eggjs常用设置

端口设置

  1. config\config.default.js 文件中设置IP和端口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // config\config.default.js
    module.exports = appInfo => {

    config.cluster = {
    listen: {
    hostname: '192.168.1.8', //也就是“localhost”,不能在前面添加协议
    port: 3000 //默认值是7001
    }
    }
    return {
    ...config,
    ...userConfig,
    };
    };

跨域设置

  1. 安装跨域所依赖的插件 egg-cors

    1
    2
    3
    "dependencies": {
    "egg-cors": "^2.2.3"
    },
  2. 开启 egg-cors

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //打开文件 ...\config\plugin.js

    module.exports = {
    //使能插件
    cors: {
    enable: true,
    package: 'egg-cors'
    },
    };

  1. 配置egg-cors插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // config\config.default.js

    module.exports = appInfo => {
    /***************设置可以跨域 Start*****************/
    config.security = {
    csrf: {
    enable: false,
    csrf: false,
    },
    domainWhiteList: ['*'] //白名单
    };
    config.cors = {
    origin: '*',
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS'
    };
    /***************设置可以跨域 end*****************/

    return {
    ...config,
    ...userConfig,
    };
    };

koa-body 中间件使用

  1. 安装插件 koa-body

    1
    2
    3
    "dependencies": {
    "koa-body": "^4.2.0"
    },
  1. …\app\router.js 路由文件中配置 koa-body 中间件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //app\router.js

    //中间件 支持post请求获取参数
    const koaBody = require('koa-body')({
    multipart: true, // 允许上传多个文件
    });


    module.exports = app => {
    const { router, controller } = app;
    //配置post 请求方式支持中间件
    router.post('/', koaBody ,controller.home.index);
    };
  2. 在控制器Controller中获取 post 请求参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class HomeController extends Controller {
    async index() {
    const { ctx } = this;
    // 获取post请求的 请求参数
    const param = ctx.request.body
    console.log(param)

    ctx.body = 'hi, egg';
    }
    }

    mysql

    1. 安装 插件

      1
      2
      3
      "dependencies": {
      "egg-mysql": "^3.0.0"
      },
    2. 开启 egg-mysql

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      //config\plugin.js

      module.exports = {

      // 开启 egg-mysql
      mysql: {
      enable: true,
      package: 'egg-mysql',
      }
      };

    3. 配置mysql

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      //config\config.default.js

      module.exports = appInfo => {

      // 配置egg-mysql
      config.mysql = {
      client: {
      // host
      host: '192.168.1.8',
      // 端口号
      port: '3306',
      // 用户名
      user: 'root',
      // 密码
      password: 'root',
      // 数据库名
      database: 'mydb',
      },
      // 是否加载到 app 上,默认开启
      app: true,
      // 是否加载到 agent 上,默认关闭
      agent: false,
      }
      return {
      ...config,
      ...userConfig,
      };
      };


  1. 设置 mysql 可以远程连接

    1. cmd 打开命令行窗口 进入 mysql

      1
      mysql -u root -p
    2. 进入要远程的数据库 use mydb

    3. 创建远程访问用户

      1
      GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY '123456' WITH GRANT OPTION;

      root 是用户名, 123456 是密码根据需要更改

    4. 更新权限

      1
      flush privileges;
    5. 可以远程访问mysql 了

文件上传

  1. 安装 插件 npm install fs-extra
    1. node-fs-extra
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
'use strict';
const fs = require('fs');
const path = require('path')
const fse = require('fs-extra')
const Controller = require('egg').Controller;

class Upload extends Controller {
async index() {
const { ctx } = this;
//获取上传的文件
const { name, path: filePath, size, type } = ctx.request.files.pic
const dest = path.join(__dirname, '../public/upload', name) // 目标目录,没有没有这个文件夹会自动创建
await fse.move(filePath, dest) // 移动文件

ctx.body = {
name, // 文件名称
filePath, // 临时路径
size, // 文件大小
type // 文件类型
}
}
}

module.exports = Upload;