egg.js(用nodejs写后台服务)

2,354 阅读4分钟

个人随笔记录 仅为个人笔记。

1.搭建eggjs

首先创建一个文件夹blog-server-egg(有的脚手架是生成文件夹,有的是安装在当前文件夹) 全局安装egg先npm i egg-init -g

使用脚手架 npm init egg --type=simple

但是依赖包不会自己下,所以还要安装一下npm i

跑起来npm run dev

2.简单说一下egg文件的概况

egg 是约定大于配置的。很多地方的写法就是官方约定的,这样的好处就是风格统一。一千个观众眼中只有一个哈姆雷特

2 目录结构

2.1目录结构

egg-project
├── package.json
├── app.js (可选)
├── agent.js (可选)
├── app(项目开发目录)
|   ├── router.js (用于配置 URL 路由规则)
│   ├── 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

2.2执行模式

请求->路由->匹配控制器->业务逻辑(穿插service层||db层)->响应

2.3一些额外的安装包以及作用

2.3.1 egg-mysql

npm i egg-mysql

使用前,还需要一些数据库基础配置 两个文件夹需要配置 config/config.default.js

/**
   * built-in config
   * @type {Egg.EggAppConfig}
   **/
  const config = (exports = {});
    // 配置数据库
  config.mysql = {
    client: {
      host: "127.0.0.1",
      port: "3306",
      user: "root",
      password: "123456",
      database: "react_blog"
    },
      // 是否加载到 app 上,默认开启
    app: true,
    // 是否加载到 agent 上,默认关闭
    agent: false
  };

config/plugin.js 开启

module.exports = {
  mysql: {
    enable: true,
    package: "egg-mysql"
  }
};

然后就可以在controller或者servive中使用this.app.mysql.query(${sql})调用了。(注意调用sql查询是一个异步。一定要等待返回,不然拿不到值)

 async index() {
    let sql = "select * from article";
    let res = await this.app.mysql.query(sql);
    console.log(res);
    this.ctx.body = "Hello egg";
  }

自己设定的一些小配置

1.eslint的单双引号问题。

eslint-config-egg这个配置默认是用单引号。修改配置文件.eslintrc中 原来

{
  "extends": "eslint-config-egg"
}

修改为

{
  "extends": "eslint"
}

2.路由文件切割。

在app文件下建立一个同级router文件 例如我需要同时提供博客前台和博客admin后台管理的接口。 所以我就这样

├── app(项目开发目录)
|   ├── router(自定义的路由切割文件)
│       ├── admin.js (这是提供给后台管理的文件)
│       ├── blog.js (这是给前台博客使用的)
|   ├── router.js (egg约定的路由文件入口,还是要引入到这里)

3.设置统一的返回格式

利用egg提供的helper扩展。在app下创建一个extend文件夹,里面放helper.js

├── app(项目开发目录)
|   ├── extend(扩展文件)
│       ├── helper.js (扩展的。你可以认为是utils)

helper.js中简单代码

module.exports = {
  /**
   * 调用正常|失败情况的返回数据封装
   * @param {data}
   * return {code:number,msg:string,data:object}
   */
  success(data) {
    return {
      code: 200,
      msg: "success",
      data
    };
  },
  fail(data) {
    return {
      code: 500,
      msg: "fail",
      data
    };
  }
};

helper可以在ctx中取到。就是说,你的数据查询成功返回可以这样

    let res = await this.app.mysql.query(sql);
    this.ctx.body = this.ctx.helper.success(res);

4.开启csrf(解决post请求missing csrf token)

npm i egg-cors 在config/config.default.js中配置

  config.security = {
    csrf: {
      enable: false
    },
    domainWhiteList: ["*"]
  };
  config.cors = {
    origin: "http://localhost:3000", //允许哪些域名可以进行接口访问.也可以使用*
    credentials: true, //允许cookie可以跨域.对应的axios的withCredentials:true。而且orgin为指定地址。
    allowMethods: "GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS"
  };

在config/plugin.js中配置

  cors: {
    enable: true,
    package: "egg-cors"
  }

3.观察一下内置对象的api和作用

1.1 Application(app)

是一个全局应用对象。在一个应用只会实例化一个 可以在控制器中this.app===this.ctx.app 中取到 使用场景:

  • 在配置路由时,app会被注入。app中可以解析出router路由和controller控制器

1.2 Context(ctx)

Context是一个请求级别的对象。ctx在很多框架中都出现过(java若依)。也就是说,你的每次请求,框架都会实例的一个ctx对象。这个对象中包括request请求对象,response响应对象等等。信息很多,很重要

使用场景

  • Controller控制器中。根据ctx.request获取请求的相关参数。另外this.ctx.body其实是this.ctx.response.body的简写。
  • Middleware 中间件中。例如你需要对所有请求拦截,判断是否登录再是否放行,所以一定会用到ctx上下文对象。
  • Service中就不用说了。业务处理层,一样可以调用。

1.3 Request&Response

也是请求级别。可以从ctx这个上下文对象中获取

1.4 Controller

框架提供了一个Controller几类。推荐所有的Controller都继承。 属性有

  • ctx - 当前请求的 Context 实例。this.ctx获取
  • app - 应用的 Application 实例。this.app获取
  • config - 应用的配置。this.config获取
  • service - 应用所有的 service。this.service获取
  • logger - 为当前 controller 封装的 logger 对象。this.logger获取

1.5 Service

和Controller相似

1.6 Helper

Helper用来提供一些使用utilty函数。Helper中封装一下独立的功能函数。 Helper自身是一个类。和Contoller一样的属性。每次请求也会进行实例化

1.7 Config

将硬编码写到配置文件中。

每次请求都会生成一个,包含了请求的信息request请求,response响应

参考: 技术胖www.jspang.com/学到很多 raoenhui.github.io/nextjs/2018…nextjs中文文档