egg.js基础入门,前端迈向全栈开发的第一步

最近实习时接手了一个Egg.js + TypeScript的服务端的项目,mentor对我说可以让我先学习一下egg.js,于是最近都在捣鼓egg.js,有了一点小收获于是准备先记录下来,避免自己之后又忘记了。

1. Egg.js 简介

Egg.js是什么?它的官方文档是这样说的:

Egg.js 为企业级框架和应用而生。我们希望 Egg.js 能孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本。

众所周知,node是具备后端开发的能力的,而egg.js就是为了方便后端开发而诞生的一种框架,就和我们之前介绍过的koa一样,而恰好,Egg又是继承于koa的,都是基于中间件开发,都是基于洋葱模型。

Egg 奉行"约定优于配置 "。按照一套统一的约定开发应用时,团队成员可以减少学习成本,不再是"钉子",能流动起来。未有约定的团队,沟通成本极高,因为每个人的开发习惯可能都不同,容易犯错。但约定并不意味着扩展性差,Egg 的扩展性极高,可根据不同团队的约定来定制框架。使用 Loader,框架能够根据不同环境定义默认配置,并覆盖 Egg 的默认约定。

这是官方文档对于它的描述。好的,废话不多说,我们来看看它的一些简单的语法吧。

2. Egg.js 目录结构介绍

我们可以使用这条命令npm init egg --type=simple来快速初始化一个egg.js项目,一般egg.js的目录结构会有这几项内容:

其中app目录与config目录是最重要的两个目录,我们着重介绍一下这两个:

我们说过,egg.js奉行的是"约定优于配置"的开发方式,所以每个文件夹是做什么的都是约定好的:

js 复制代码
app
├── controller        # 控制器(处理请求)
├── service           # 服务层(业务逻辑)
├── model             # 数据库模型(可选)
├── middleware        # 中间件
├── router.js         # 路由配置
config
├── config.default.js # 默认配置
├── plugin.js         # 插件配置

在egg.js中,还有一个非常重要的东西叫Context(上下文对象),各个文件夹之间的联通主要来靠它。每次请求会创建一个 Context 对象,它封装了Node.js 的 request 和 response 对象,并提供了一系列便捷方法。

我们可以在 Controller、Middleware、Service、Helper 中通过 this.ctx 访问。

接下来,我们将一一介绍一下app下的各个文件的作用是什么。

3. app/router.js 文件

作用:定义 URL 路由规则,将请求映射到 Controller。

示例配置:

js 复制代码
module.exports = app => {
  const { router, controller } = app;
  router.post('/user/create', controller.user.create);
  router.get('/user/list', controller.user.find);
};

当我们通过http请求访问/user/create或/user/list,就会调用对应的UserController.create 方法。

4. app/controller 目录

作用:处理 HTTP 请求,负责路由与业务逻辑之间的桥梁。

示例文件:app/controller/user.js

js 复制代码
const Controller = require('egg').Controller;

class UserController extends Controller {
  async create() {
    const { ctx } = this;
    const { name, age } = ctx.request.body;
    // 调用 Service 处理业务逻辑
    const user = await ctx.service.user.createUser(name, age);
    ctx.body = { success: true, data: user };
  }

  async find() {
    const users = await this.ctx.service.user.getUsers();
    this.ctx.body = users;
  }
}
module.exports = UserController;

用途:定义 /user/create 和 /user/find 路由对应的逻辑,联通service业务层。

5. app/service 目录

作用:封装业务逻辑(如数据库操作),供 Controller 调用。

示例文件:app/service/user.js

js 复制代码
const Service = require('egg').Service;

class UserService extends Service {
  async createUser(name, age) {
    // 假设使用 Egg.js 的 MySQL 插件
    const result = await this.app.mysql.insert('users', { name, age });
    return { id: result.insertId, name, age };
  }

  async getUsers() {
    return await this.app.mysql.select('users');
  }
}
module.exports = UserService;

用途:处理用户创建和查询的数据库操作。

6. app/middleware 目录

作用:存放中间件,用于拦截和处理请求。

示例文件:app/middleware/logger.js

js 复制代码
module.exports = (options, app) => {
  return async function logger(ctx, next) {
    const start = Date.now();
    await next(); // 执行后续中间件和路由
    const duration = Date.now() - start;
    console.log(`[${ctx.method}] ${ctx.url} - ${duration}ms`);
  };
};

配置启用:在 config/config.default.js 中:

js 复制代码
exports.middleware = ['logger']; // 启用中间件

7. app/view 目录

作用:存放模板文件(如 HTML 模板)。

示例文件:app/view/user/list.tpl

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <title>User List</title>
</head>
<body>
  <h1>Users</h1>
  <ul>
    {% for user in users %}
      <li>{{ user.name }} ({{ user.age }})</li>
    {% endfor %}
  </ul>
</body>
</html>

在 Controller 中渲染:

js 复制代码
async list() {
  const users = await this.ctx.service.user.getUsers();
  await this.ctx.render('user/list.tpl', { users });
}

8. app/extend 目录

作用:扩展 Egg.js 的核心对象(如 Application、Context 等)。

示例文件:app/extend/context.js

js 复制代码
module.exports = {
  formatUser(user) {
    return `User: ${user.name} (ID: ${user.id})`;
  }
};

使用扩展方法:

js 复制代码
// 在 Controller 中
ctx.formatUser(user); // 输出 "User: Alice (ID: 1)"

9. config 目录

作用:存放项目配置,区分不同环境(如开发、测试、生产)。

关键文件:

config.default.js(通用配置):

js 复制代码
exports.mysql = {
  client: {
    host: 'localhost',
    port: '3306',
    user: 'root',
    password: '123456',
    database: 'test',
  },
};

config.prod.js (生产环境覆盖配置)

js 复制代码
exports.mysql = {
  client: {
    host: 'prod.db.com', // 生产环境数据库地址
  },
};

10. 其他目录

  • ​app/public​:存放静态文件(如图片、CSS)。
  • ​app/schedule​:定时任务配置。
  • ​app/utils​(非官方约定):存放工具类函数。

11. 总结

简单总结来说的话,就是用户访问 /user/list,router.js 将请求路由到 UserController.list,Controller 调用 UserService.getUsers(),Service 通过 app.mysql 查询数据库,Controller 使用 ctx.render 渲染模板,返回 HTML 页面或 JSON 数据。

egg.js的内容远不止这些,本次只是对于egg.js的目录的一些简单的介绍,如果对你有帮助的话请点个赞吧。

相关推荐
夏幻灵3 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
三天不学习3 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs194054 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
明月_清风5 小时前
Deno 终局来了:从挑战 Node 到被 Cloudflare 收编
前端·后端·node.js
guslegend9 小时前
脚手架原理与本地调试:从 bin 软链接到 npm link
前端·npm·node.js·脚手架·前端工程化
小宋10219 小时前
A2UI从零实战:Agent安全生成交互界面与事件回传
javascript·人工智能·安全·交互
大包子10 小时前
structuredClone vs lodash.cloneDeep:核心差异与选型指南
javascript·vue.js
lerhxx10 小时前
AI 应用中的上下文管理 —— 从"上下文窗口"到"分层压缩"的工程实践
前端·javascript
Mahut11 小时前
我在 Mac 上做了个本地剪辑器
javascript·架构·产品
zReadonly11 小时前
不用反复 nvm use 了:nvm-windows 2.x 按项目自动切换 Node.js
前端·node.js