这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
1.Egg.js和Express,Koa.js对比
Express 是 Node.js 社区广泛使用的框架,简单且扩展性强,非常适合做个人项目。
Koa 和 Express 的设计风格非常类似,Koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架
而 Egg 选择了 Koa 作为其基础框架,在它的模型基础上,进一步对它进行了一些增强。总结来说具有以下特点。
2.Egg.js的项目搭建(借助官方egg脚手架)
初始化项目
$ mkdir egg-example && cd egg-example
$ npm init egg --type=simple
$ npm i
启动项目
$ npm run dev
$ open http://localhost:7001
脚手架主要是安装了egg,egg-bin两个重要包,然后手动搭建controller,service层。官方脚手架提供了标准的脚手架目录结构,有兴趣的参考官网搭建。网络卡顿的可以安装nrm切换npm镜像源。后期我会做一期搭建私有npm源
npm i nrm -g
##查看镜像源
nrm ls
##使用指定的镜像源比如yarn
nrm use yarn
##切换后始终使用npm i xx包,nrm会自动帮助切换
npm i xxx
访问本机7001端口会看到hi egg
##注意:如出现node版本和egg版本冲突无法跑起代码的情况,直接安装报错要求一步步来就能成功运行
3.目录讲解
动手改造目录结构(注意egg是约定大于配置,也就是通过扫描controller下面的文件作为controller,不用手动注册,所以文件名严格按照规范,后期学习的nest.js就需要手动注册,但可以封装成egg这样)
app层--->controller(用户处理restful api的各种接口,功能处理调用service)
app层--->service(用于处理更加繁琐,比如数据库增删查改的方法等等)
app层--->routes(用于路由和controller方法的匹配,比如/user/read对应usercontroller的read方法,这个时候需要对应)
app层--->public(放置一些静态资源)
app层--->middleware(中间件都写这下面)
app层--->extend(延展context的方法和工具类都可以在里面写)
app层--->exception(继承并重写默认的异常处理码)
config--->config.default.js(用于配置安装的插件的一些参数,比如数据库的密码等等,jwt的密码等等)
config--->config.prod.js(内容和config.default.js一样,但是可以分别修改上线的一些参数等等,将测试环境和线上的数据库分开等等)
config--->plugin.js(npm安装的插件,都必须要在这里打开)
4.简单接口编写
首先配置路由
/user/read------>controller的某个方法
router.get("/user/read", controller.user.read);
controller
"use strict";
const Controller = require("egg").Controller;
class UserController extends Controller {
async read () {
const { ctx } = this;
const data = await this.service.user.findUser();
ctx.body = data;
}
}
module.exports = UserController;
service
const Service = require("egg").Service;
class UserService extends Service {
async findUser() {
return "indexService";
}
}
module.exports = UserService;
目录展示,严格为约定大于配置,controller里面直接调用service目录里面的文件方法,都是挂载在中央对象上面的。
5.配置跨域插件
前端使用axios访问接口的时候会出现跨域的情况,我们可以通过vue cli创建一个前端项项目模拟一下
- cli创建前端项目
vue create test
- 安装axios请求包
npm i axios --save
- 简单的前端请求代码
<script>
import axios from "axios";
export default {
created() {
this.init();
},
methods: {
async init() {
const res = await axios.get("http://localhost:7001/user/read");
console.log(res);
},
},
};
</script>
结果:cors跨域保护
4. 按照egg-cors插件
npm i egg-cors --save
在plugin.js开启插件
// 配置跨域插件
exports.cors = {
enable: true,
package: 'egg-cors',
};
在config.default.js配置跨域允许的白名单,domainWhiteList里面可以配置你所需要的前端请求链接
// 配置csrf的跨域攻击
config.security = {
csrf: {
enable: false,
},
domainWhiteList: [ '*' ],
};
6.编写helper工具类
在app-extend里面编写helper.js文件,注意名称一定要对,约定大于配置的思想
我们开发一个项目,肯定有很多通用工具类需求封装,比如说时间格式转换相当的常用。
helper.js
const dayJs = require("dayjs")
module.exports = {
formateDate (date) {
return dayJs(date).format('DD/MM/YYYY')
}
}
controller.js
this.ctx.helper.formateDate('2019-01-25')
7.全局context全局处理
context全局上下文对象,使用this.ctx访问,我们可以ctx扩展方法
例:对于egg中我们controller每次都需要响应请求,但是请求格式每次自己写状态码code字段,返回值msg字段。一是容易写错,二是联调需要改个字段会显得相当的复杂。
'use strict';
module.exports = {
// 封装响应数据格式
responseData(data = {}, msg = 'success', code, status = 200) {
this.status = status;
this.body = {
status: code,
data,
msg,
};
},
controler.js
this.ctx.responseData({a:1},"查询a值成功",200)
8.params和query,body接收参数方式
query
在 URL 中 ? 后面的部分是一个 Query String,这一部分经常用于 GET 类型的请求中传递参数。例如 GET /posts?category=egg&language=node
controller.js
const query = this.ctx.query;
// {
// category: 'egg',
// language: 'node',
// }
params
GET /projects/1/app/2
controller.js
this.ctx.params.projectId
body
POST /api/posts HTTP/1.1
controller.js
this.ctx.request.body.title
this.ctx.request.body.content