Egg简介

2023-10-26

Egg

前言

Egg.js 为企业级框架和应用而生。基于Koa开发封装,性能优异,内置多进程管理,具有高扩展性,且提供了基于Egg定制上层框架的能力,帮助开发团队降低了开发维护成本。

约定先于配置,相较于express更加灵活可配。

Koa

Koa是Express原班人马导致的,致力于web应用和API领域更小,更丰富的web框架。其和express设计风格类似,底层采用同一套HTTP基础库。

  • koa采用中间件洋葱图,所有请求经过一个中间件时均会被执行2次,可以方便进行后置逻辑处理,而express中间件只会执行一次
  • koa新增了Context对象,其作为上下文贯穿整个请求过程,其上也挂载了ResquestResponse对象,而express只有ResquestResponse挂载在中间件上。
  • 使用async await,可以同步的方式书写异步代码,书写便捷,异常捕获错误。

使用

安装egg

npm install -g egg

使用脚手架搭建项目

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

npm run dev 启动项目,默认可访问http://localhost:7001

约定目录

egg-project
├── package.json
├── app.js (可选)							//项目入口文件
├── agent.js (可选)						//进程处理,例如日志打印等
├── app
|   ├── router.js							//路由定义
│   ├── controller						//处理用户输入,返回所需结果
│   |   └── home.js
│   ├── service (可选)				 //处理业务层逻辑,调用后端api
│   |   └── 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

文件加载顺序

  • 加载 plugin,找到应用和框架,加载 config/plugin.js
  • 加载 config,遍历 loadUnit 加载 config/config.{env}.js
  • 加载 extend,遍历 loadUnit 加载 app/extend/xx.js
  • 自定义初始化,遍历 loadUnit 加载 app.jsagent.js
  • 加载 service,遍历 loadUnit 加载 app/service 目录
  • 加载 middleware,遍历 loadUnit 加载 app/middleware 目录
  • 加载 controller,加载应用的 app/controller 目录
  • 加载 router,加载应用的 app/router.js

优先级:插件>框架>应用,被依赖的优先加载,越底层的越先加载

生命周期

app.js

// 项目启动时执行
class AppBootHook {
    constructor(app) {
      this.app = app;
    }
  
    configWillLoad() {
      console.log("配置文件即将加载,这是最后动态修改配置的时机")
    }
  
    configDidLoad() {
        console.log("配置文加载完成,可在此处获取配置文件信息")
    }
  
    async didLoad() {
        console.log("所有文件加载完成")
    }
  
    async willReady() {
        console.log("插件启动完成")
    }
  
    async didReady() {
        console.log("worker准备就绪")
    }
  
    async serverDidReady() {
        console.log("应用启动完成,服务已在监听状态")
    }
  
    async beforeClose() {
        console.log("应用即将关闭")
    }
  }
  
  module.exports = AppBootHook;

路由

路由配置在:app/router.js

router.get(routerName, path,middleware,controller);
  • routerName:路由别名
  • path:路由可访问的路径
  • middleware:中间件(可选)
  • controller:映射到具体的controller逻辑方法

get为路由请求方式,controller会以.为区分,查找app/controller目录下对用的文件,最后一个标识表示controller中的method名,如果不存在则默认访问index()

例如:

  router.post('/admin', isAdmin, app.controller.admin);

isAdmin是中间件,访问/admin时,将执行app/controller/admin文件下的index()

请求参数获取

//get请求
let name = ctx.query.name

//post请求
let name = ctx.body.name

//路由上动态参数
let name = ctx.params.name

内置对象

  • Application:全局唯一实例对象,在应用任意地方均可以获取。获取方式:this.app
  • Context:请求级别对象,包含了用户请求信息响应信息,一般存在于MiddlewareControllerService中。获取方式:this.ctx
  • Config:应用配置信息,存在于ControllerServiceHelper获取方式:app.configthis.config
  • Logger:日志对象。使用方式:app.logger

ControllerServiceHelper:这三个类,均内置了如下属性:

  • ctx - 当前请求的 Context 实例。
  • app - 应用的 Application 实例。
  • config - 应用的配置
  • service - 应用所有的 service
  • logger - 为当前 controller 封装的 logger 对象。
  • helper-公共函数辅助对象

中间件

中间件配置在:app/middleware下。

写法

module.exports = (options,app)=>{
    //每个中间件都接收2个参数,options:中间件属性,app:应用实例对象
    //可获取配置信息
    return async (ctx, next) => {
        //中间件返回一个异步的方法,方法接收2个参数,ctx:请求上下文,next:下一次执行的函数
        //中间件逻辑处理
        await next()
        
    }
}

每个中间件都接收2个参数,options:中间件自定义配置,app:应用实例

其需要导出一个异步函数。

使用

定义好的中间件需要我们手动进行加载配置。

config/config.default.js中定义需要加载的中间件,然后配置其所需属性

  config.middleware = [
    "test"	//注册test中间件需要加载
  ];

  config.test = {	//test中间件属性配置
    name: "中间件测试"
  }

每个中间件都有3个默认属性:

  • enable:控制中间件是否开启。
  • match:设置只有符合某些规则的请求才会经过这个中间件。
  • ignore:设置符合某些规则的请求不经过这个中间件。

控制器(Controller)

所有的controller文件均应放在app/controller目录下,因为应用约定在该目录下查找路由对应的逻辑处理,支持多级目录。

写法

// app/controller/post.js
const Controller = require('egg').Controller;
class PostController extends Controller {
  async create() {
    const { ctx, service } = this;
    const createRule = {
      title: { type: 'string' },
      content: { type: 'string' },
    };
    // 校验参数
    ctx.validate(createRule);
    // 组装参数
    const author = ctx.session.userId;
    const req = Object.assign(ctx.request.body, { author });
    // 调用 Service 进行业务处理
    const res = await service.post.create(req);
    // 设置响应内容和响应状态码
    ctx.body = { id: res.id };
    ctx.status = 201;
  }
}
module.exports = PostController;

每个自定义控制器都应该继承eggController类,这样才能将内置属性挂载到自定义控制器上。

每个方法都应该是一个async await函数

每个文件只能存在一个导出类,必须用module.exports导出。

模板渲染

Context提供了3个Promise接口进行模板渲染。

  • render(name, locals) 渲染模板文件, 并赋值给 ctx.body
  • renderView(name, locals) 渲染模板文件, 仅返回不赋值
  • renderString(tpl, locals) 渲染模板字符串, 仅返回不赋值

locals为需要传递给前端的数据,是一个对象

数据返回

ctx.body=data

服务(Service)

所有的controller文件均应放在app/service目录下。支持多级目录

// app/service/user.js
const Service = require('egg').Service;

class UserService extends Service {
  async find(uid) {
    const user = await this.ctx.db.query('select * from user where uid = ?', uid);
    return user;
  }
}

module.exports = UserService;

每个方法都应该是一个async await函数,且必须继承egg.Service

每个文件只能存在一个导出类,必须用module.exports导出。

service的ctx可以发起请求,也可以访问数据库。

  • this.ctx.curl 发起网络调用。
  • this.ctx.service.otherService 调用其他 Service。
  • this.ctx.db 发起数据库调用等, db 可能是其他插件提前挂载到 app 上的模块。

模板渲染

egg支持egg-view-nunjucks模板引擎,静态资源模板采用egg-view-assets

插件下载

npm i egg-view-nunjucks --save
npm i egg-view-assets --save

启动插件

// config/plugin.js
module.exports = {
  assets: {
    enable: true,
    package: 'egg-view-assets',
  },
  nunjucks: {
    enable: true,
    package: 'egg-view-nunjucks',
  }
};

插件配置

// config/config.default.js
//配置模板根目录,这样在controller中render时则可省略根目录直接在该目录下查找指定文件
config.view = {
    root: path.join(appInfo.baseDir, 'app/view/entry'),
    mapping: {
      ".jsx": "assets"
    }
  }

//指定模板位置,编译后输出位置,本地测试打包配置devServer
  config.assets={
    templatePath:path.join(appInfo.baseDir, 'app/view/template/index.html'),
    templateViewEngine: 'nunjucks',
    devServer: {
      command: 'roadhog dev',
      debug: true,
      port: 8000,
      timeout:180*1000,
      env: {
        BROWSER: 'none',
        ESLINT: 'none',
        SOCKET_SERVER: 'http://127.0.0.1:8000',
        PUBLIC_PATH: 'http://127.0.0.1:8000',
      },
    },

使用
模板文件app/view/template/index.html

<!doctype html>
<html>

<head>
    <meta charset="utf-8" />
    <title>模板渲染</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    {{ helper.assets.getStyle() | safe }}
</head>

<body>
    <div id="ReactApp"></div>
    {{ helper.assets.getScript() | safe }}
</body>

</html>

helper.assets可动态的获取render参数,并且生成可访问的映射路径,例如:home.js -> http://127.0.0.1:8000/home.js
默认情况下publicPath:"/",如果配置publicPath:"public,则映射关系也将改变,home.js -> http://127.0.0.1:8000/public/home.js

webpack配置,.webpackrc

{
  "entry": "app/view/entry/*.jsx",
  "extraBabelPlugins": [
    [ "import", { "libraryName": "antd", "style": true } ]
  ],
  "outputPath": "app/public",
  "disableCSSModules": true,
  "hash": true,
  "manifest": {
    "fileName": "../../../config/manifest.json"
  }
}

这里引入了antd,所以package.json需含有 @babel/corebabel-plugin-import这两个依赖。
roadhog在开发环境下publicPath永远为/

入口文件,app/view/entry/home.jsx

import React from "react";
import ReactDom from "react-dom";

const Home = () => {
    return (
        <div>我是入口模板</div>
    )
}

ReactDom.render(<Home />, document.getElementById('ReactApp'));

模板渲染,app/controller/home.js

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

class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    await ctx.render("home.jsx");
  }
}
module.exports = HomeController;

参考地址

egg官网:https://eggjs.org/zh-cn/basics/structure.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Egg简介 的相关文章

  • 当node遇上Egg遇上TypeScript

    快速入门 通过骨架快速初始化 xff1a npx egg init type 61 ts showcase cd showcase amp amp npm i npm run dev 上述骨架会生成一个极简版的示例 xff0c 更完整的示例
  • Egg简介

    Egg 前言 Egg js 为企业级框架和应用而生 基于Koa开发封装 性能优异 内置多进程管理 具有高扩展性 且提供了基于Egg定制上层框架的能力 帮助开发团队降低了开发维护成本 约定先于配置 相较于express更加灵活可配 Koa K
  • koa返回前端响应后,后台静默做其他操作

    需求描述 后端使用Koa框架 需要接收到请求后立即给予前端响应 后续由后端继续做其他异步调用API的操作 遇到的问题 Koa中返回前端响应的方式有两种 一种是直接return你需要的响应参数 另一种则是设置响应body 接口方法走完后就会自
  • AI,v3,百度人脸识别库上传---node

    config有必要的grant type client id client secret var https require https var request require request var qs require querystr
  • egg.js和nest.js的对比

    egg js和nest js的对比 前几天突然看到一个群在说现在用egg的人已经很少了 说用nest的人比较多 然后我就做了一个简单的调查和对比 egg和nest都是比较优秀的框架 但是两个框架有比较大的区别 我主要分为六个方面来分析egg
  • 分享一波js,node,vue等相关的书籍

    作者在空闲时间看了一些关于js node vue等相关的一些书籍 为了方便有需要的朋友一起学习 所以将这些书籍分享给大家 大家如果有需要的可以根据自己的需要下载 书籍清单 css相关 CSS那些事儿 flex布局相关 Flex 3权威指南
  • Koa项目搭建----从零搭建Koa项目

    最近发现使用 Koa 创建项目的博客比较多 但是不够细致 为方便自己和他人 遂整理本博客 本博客会介绍以下内容 1 安装Koa脚手架 即 koa generator 2 创建 Koa 1 项目 3 创建 Koa 2 项目 4 坑 5 项目运
  • NodeJS分别实现token、cookie登录注册鉴权(KOA2)

    源码 https github com NaCl 131 node study git 包 npm install koa npm i nodemon D 保存自动更新 npm i koa router 路由 npm i koa body
  • egg初始化搭建swagger项目

    步骤 安装node 安装你喜欢的编辑器 初始化项目 输入安装 egg 命令 输入安装 egg dev 命令 修改 package json 基本目录结构 需手动创建 输入安装 egg sequelize 命令 数据库选择 配置 sequel
  • 【Vue + Koa 前后端分离项目实战9】使用开源框架==>快速搭建后台管理系统 -- part9 项目总结

    去读书 去学一门手艺 去做任何自己喜欢的事 永远不会晚 才不会辜负这份人生 本博客教学视频来源于imoom 0到1快速构建自己的后台管理系统 课程 官方演示地址 https talelin com 目录 一 项目介绍 1 技术准备 2 学到
  • 【nodejs进阶之旅(2)】:使用koa2+mysql 实现列表数据分页

    1 展示效果 分页 2 分页主要字段 分页主要字段包括 pageSize 每页条数 pageNum 第几页 startRow 当前开始页编号 endRow 当前结束页编号 total 总数量 主要是根据前端分页的参数 进行处理后 返回前端正
  • 从 python bdist_egg 或 bdist_wheel 中排除单个源文件

    背景 我有一个负责安全性的源文件 其中有神奇的钥匙和特定的算法 是否可以从 python Egg 或 Wheel 包中删除这个单个源文件 我已经完成了使用 Egg 命令仅发送二进制文件 python setup py bdist egg e
  • 如何告诉 Buildout 从 URL 安装 Egg(不带 pypi)

    我有一些可以通过 URL 访问的彩蛋 比如说http myhosting com somepkg egg 现在我没有在 pypi 上列出这个 somepkg 我如何告诉 buildout 为我获取并安装它 我尝试了一些食谱 但到目前为止还没
  • 如何更新Python Egg中的文件

    我们正在使用 trac 在我们的设置中 我们有一个在存储库中解决的问题 因此 我从存储库中获取了固定文件 commit update py 我需要将其放入 Trac 0 12 py2 6 egg 中 由于 Egg 只是一个压缩文件 我只是将
  • 如何在不安装Python Egg文件的情况下直接运行它们?

    是否可以像使用 Java 运行 jar 文件一样直接运行 Python Egg 文件 例如 使用 Java 您可能会执行以下操作 java jar jar file A 蟒蛇蛋 http peak telecommunity com Dev
  • 无法获取店铺名称

    在以前的版本中我用来获取当前商店名称是这样的 router get api app async ctx gt let shop ctx session shop 但是 在新版本中 我无法使用 ctx session shop 获取当前商店名
  • Koa.js - 提供静态文件和 REST API

    我是 koa js 库的新手 我需要一些帮助 我正在尝试使用 koa 制作简单的 REST 应用程序 我有一个静态 html 和 javascript 文件 我想在路线上提供服务 和 REST API 访问 api 这是我的项目目录树 pr
  • 在 Mongoose 之上使用 Joi 进行验证是一个好的实践吗?

    我正在使用 Node js Mongoose 和 Koa 开发 RESTful API 但在架构和输入验证方面 我对最佳实践有些困惑 目前 我对每个资源都有 Mongoose 和 Joi 模式 Mongoose 架构仅包含有关特定资源的基本
  • 如何在http请求中设置边界?

    我正在尝试在 Ajax 请求中发送多部分 表单数据 我正在使用 node busboy 来解析多部分数据 但它一直抛出错误 Error Multipart Boundary not found 我读过了here https stackove
  • 导入 BitTorrent Bencode 模块

    我使用的是 Mac OS X 10 6 Python 是 2 6 1 我已经安装了 Bencode 模块 sudo easy install BitTorrent bencode 它出现在站点包中 Library Python 2 6 si

随机推荐

  • 未来城市规划

    未来城市规划 题目描述 n n n 个节点的树 m m m 次操作 每个边都有初始边权 c
  • Kubernetes将会在1.24版本中弃用dockershim

    点击上方 分布式实验室 关注公众号 回复 1 抽取技术书 Kubernetes 计划在即将发布的 1 24 版本里弃用并移除 dockershim 使用 Docker 引擎作为其 Kubernetes 集群的容器运行时的工作流或系统需要在升
  • MFC的静态库.lib、动态库.dll(包含引入库.lib)以及Unicode库示例

    以vs2012为标准 转自 http technet microsoft com zh cn library w4zd66ye 有改动 一 MFC的静态库 lib MFC静态库使用下列命名约定 uAFXcWd LIB 库命名约定的说明符如下
  • VOSviewer 操作指南 简明

    VOSviewer 操作指南 Vosviewer 软件是一种知识图谱可视化软件 并且可以使用基本的分类聚类方法 帮助我们得到进一步的信息 下载地址 https www vosviewer com download 解压完成后 你得到因该是一
  • 27 个为什么,帮助你更好的理解Python

    选自 Python官方文档 https docs python org zh cn 3 7 faq design html
  • pytorch报错:RuntimeError: CUDA error: device-side assert triggered究极解决方案

    原因 模型的数据处理出了问题 一般是类似于数组访问越界的问题 1 例如分类的标签是数据处理的时候是1 10 但是torch在计算交叉熵是默认是0 9 2 embedding模块的词表长度问题 比如embedding中词表总长度是100 但是
  • Unix时间与Win32 FileTime时间

    Unix 时间 1970 01 01 00 00 00 与 Win32 FileTime 时间 1601 01 01 00 00 00 两者相差毫秒数为 11644473600000L Win32 FileTime 采用 100ns 为单位
  • Postgres安装

    准备工作 1 查看自己的电脑是多少位 cmd界面中输入 systeminfo 按回车 主要是看一下系统类型 系统类型 64 位操作系统 基于 x64 的处理器 版本 Windows 10 专业版 版本号 20H2 安装日期 2021 10
  • 【IDEA】idea 调试技巧 查看字段 什么时候修改的

    文章目录 1 概述 1 概述 如果你阅读源码 你一定会有个困扰 类中的某个字段的值到底是在哪里改变的 你要一点点追踪调用栈 逐步排查 稍不留神 就可能有遗漏 我们可以在 IntelliJ IDEA 中为某个字段添加断点 当字段值有修改时 自
  • es--基础--06--es集群

    es 基础 06 es集群 1 集群概念 概念看es入门学习3 理论 2 集群的搭建 利用原有的单机 elasticsearch 5 6 8 来搭建 搭建三台es服务器 分别提供的端口是9201 9202 9203 2 1 停止elasti
  • 特征选择策略:为检测乳腺癌生物标志物寻找新出口

    内容一览 microRNA 小分子核糖核酸 是一类短小的单链非编码 RNA 转录体 这些分子在多种恶性肿瘤中呈现失控性生长 因此近年来被诸多研究确定为确诊癌症的可靠的生物标志物 biomarker 在多种病理分析中 差异表达分析 Diffe
  • 解决Dropbox国内无法实时更新的问题

    Dropbox软件需要在全局模式下才能时时同步 但全局模式下无法打开某些国内网站 所以需要解决该问题 解决方法 通过设置代理的方式让Dropbox软件自动同步 但在尝试中 设置为socks5代理发现不能使用 改为http代理 马上生效 打开
  • 十分钟带你走进Hive世界(每走一步都是为了离你更近些)

    该文章已更新到语雀中 后台回复 语雀 可获取进击吧大数据整个职业生涯持续更新的所有资料 该文基于Hive专题 从SQL聊Hive底层执行原理进一步的深入学习Hive 相信大多数童鞋对于Hive底层的执行流程只是局限于理论层面 那么本篇将带大
  • Windows平台Unity3d下如何同时播放多路RTSP或RTMP流

    好多开发者在做AR VR或者教育类产品时 苦于如何在windows平台构建一个稳定且低延迟的RTSP或者RTMP播放器 如果基于Unity3d完全重新开发一个播放器 代价大 而且周期长 不适合快速出产品 我们认为当前最好的方式就是集成现有N
  • 【计算机网络】 TCP——四次挥手

    文章目录 流程 考点 流程 主动方打算关闭连接 此时会发送一个TCP首部FIN标志位被置为1的报文 也即FIN报文 之后主动方进入FIN WAIT 1状态 被动方收到该报文后 就向主动方发送ACK应答报文 接着被动方进入CLOSE WAIT
  • Qt 6.4.2在Windows上安装过程及简单验证

    Qt是一个跨平台的C 开发库 用来开发图形用户界面 Graphical User Interface GUI 它支持Windows Linux macOS Android iOS QNX等平台 一个框架 一套代码库 任意平台部署 Qt有开源
  • Centos 8上安装Docker配置国内镜像源

    一 使用背景 在阿里云上安装docker后 如果采用国外的源地址 pull的时候 速度慢到让人崩溃 二 国内常用加速地址 Docker中国官方加速地址 https registry docker cn com 网易163镜像加速 http
  • 使用 Waffle 进行测试的基本流程及使用方法-文章来自问我社区

    前言 Waffle 是一款适配 ehter js 的智能合约测试库 本样例演示了使用 Waffle 进行测试的基本流程及使用方法 Waffle 详细使用方法可以参考 Waffle 官网 对于不熟悉 Waffle 测试框架的开发者 可以根据本
  • 腾讯Cos对象储存api用法教程中英图文讲解

    Chinar blog www chinar xin 腾讯云 Cos api sdk详解 本文提供全流程 中文翻译 Chinar 的初衷是将一种简单的生活方式带给世人 使有限时间 具备无限可能 Chinar 心分享 心创新 助力快速理解 C
  • Egg简介

    Egg 前言 Egg js 为企业级框架和应用而生 基于Koa开发封装 性能优异 内置多进程管理 具有高扩展性 且提供了基于Egg定制上层框架的能力 帮助开发团队降低了开发维护成本 约定先于配置 相较于express更加灵活可配 Koa K