Egg.js基础入门一:项目搭建与控制器

2022年4月1日,周五,已完成本周的工作安排,明天又是个工作日,想来在公司会有一天半左右的相对自由的时间,所以分几个小模块说一下Egg.js的入门内容吧,毕竟自己也是个Egg初学者,太深入的内容自己也不懂。

项目搭建

学习egg.js就从搭环境开始吧:

首先yarn create egg --type=simple创建一个egg项目,当然可以指定别的模板。

创建成功后yarn install安装相关依赖,yarn dev启动开发服务器。

egg项目内置了多种运行模式,主要说下dev与start的区别:

  • dev:开发调试模式,可以热更新而不需重启项目
  • start:线上服务模式,有进程守护,不需要pm2等插件来守护进程。

通过yarn dev启动后我们可以看到项目运行在了127.0.0.1:7001这个端口,我们可以访问试一下验证项目是否成功运行。

项目目录

通过yarn create egg --type=simple生成的项目目录大致如下:

| app # 主要代码目录

| | controller

| | public

| | router

| config # 配置

| logs # 日志文件

| run # 项目运行时生成的临时文件

| test # 用于写单元测试

| typing # 类型声明

导言

Egg.js的宗旨是约定优于配置,那么什么是约定呢? 比如下边这些就是:

  • 控制器controller需要写在 /app/controller 目录下
  • 服务service需要写在 /app/service 目录下
  • 路由必须配置在 /app/router.js 文件中
  • ejs引擎渲染的内容需要放到 /app/view 目录下
  • 单元测试写在 /test 目录下
  • 静态资源放到 /app/public 目录下
  • 插件要在 /config/plugin.js 和 /config/config.default.js 文件中配置
  • 中间件必须放到 /app/middleware 目录下
  • 对象扩展内容必须放到 /app/extend 目录下,且命名有要求
  • 定时任务必须放到 /app/schedule 目录下

如上就是一些约定,当然不理解也没什么,往下看就会理解在说什么的。如果有些目录项目中不存在可以自行创建。

Egg.js是基于Koa实现的,所以最好能简单了解一下Koa的语法、洋葱模型等,当然不了解也无伤大雅。

后续所有的代码演示,都会在第一行的注释中声明文件路径

控制器实现

大家可以好好看一下控制器的实现方式,因为service服务和定时任务的实现与控制器是极为相似的。

在演示之前先说一些规则,大家记住就好:

  • ctx上下文和app对象可以从this中取出
  • request、response、helper、cookie、session等可以从上下文ctx中取出

具体的语法就放到代码中演示了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// /app/controller/demo.js
// 记得启用严格模式
'use strict'
// 从egg中引入controller
const Controller = require('egg').Controller
// 定义一个自定义控制器类 继承自 Controller
class DemoController extends Controller {
// 类的内部就可以写控制器方法了,必须使用async
async index(){
const { ctx } = this
// 与koa一致,使用ctx.body返回内容
ctx.body = "这里是返回的内容"
}
}

// 将定义的controller暴露出去
module.exports = DemoController

注册路由

我们实现控制器之后,肯定要在路由中使用,下面介绍一下使用方法:

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

module.exports = app => {
// 解构
const { router, controller } = app
// 注册路由
// 使用 controller.文件名.方法名 的方式来制定要使用控制器
router.get('/demo', controller.demo.index)
}

接下来我们访问127.0.0.1:7001/demo,就能看到我们返回的内容了。

单元测试

每写完一个方法都进行相应的单元测试肯定是一个好习惯,接下来我们就对刚刚写的方法进行单元测试。

当然我们的示例比较简单,返回内容也很简单,实际项目中的单元测试要麻烦的多

所以在这里只是演示一个单元测试的书写语法

仿照项目生成的测试用例来书写即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// /test/app/controller/demo.test.js
'use strict'

const { app } = require('egg-mock/bootstrap')
// describe函数 , 第一个参数是描述内容
describe('test/app/controller/demo.test.js', () => {
// 正式的测试用例,it函数也接受两个参数,第一个是对测试接口的描述
it('index method test', () => {
return app.httpRequest()
.get('/demo') // 请求接口路径
.expect(200) // 期望得到的状态码
.expect('这里是返回的内容') // 期望得到的返回内容
})
})

也可以对异步任务进行测试,单元测试的方法加上async即可

1
2
3
4
5
6
7
// /test/app/controller/demo.test.js
it('index method test', async () => {
return app.httpRequest()
.get('/url') // 请求接口路径
.expect(200) // 期望得到的状态码
.expect('期望得到的返回内容') // 期望得到的返回内容
})
作者

胡兆磊

发布于

2022-04-01

更新于

2022-10-23

许可协议