记录一下
Egg
采坑道路,简要介绍:如果说Express
和Koa
属于基础框架,那么基于Koa
这个蛋就算是上层应用框架了,这个蛋本身没啥可说的,但是koa
体系常用的模块都被人重写成了egg
版,并且通过egg-plugin
在模块和应用之间架起了一个桥梁。
如果你要拿egg
对比其他框架如 Sails,那就像是Django
对比Flask
,看你个人喜欢咯:一种提供全套解决方案,一种提供社区组件拓展,大多数情况我个人并不喜欢后者。
如果你要问egg
难不难,我只能说你会Koa2
的话,一天完全可以搞定egg
。但是估计给你一年也搞定不了egg-xxx
。这个框架的命令行报错,调试方面也继承了Node.js
的老毛病。
总结起来就是一句话:这个蛋你可以来看看,但不要太费时间上去,垃圾东西。
1. 使用官方脚手架 egg-init
开始项目。
- 脚手架安装:
npm i -g egg-init
- 初始化目录:
egg-init egg-first --type=simple
- 安装项目依赖:
cd egg-first && npm i
- 热部署启动:
npm run dev
- 注意:目录结构如图。脚手架就是在
npm
仓库中下载了个模板,然后给你配置了个key罢了。- image.png
2. 手动实现 egg
项目初始化/macos && Linux
mkdir egg-api && cd egg-api
mkdir app config test
mkdir app/controller app/service
touch app/router.js config/config.default.js config/plugin.js
echo "exports.keys = 'erchoc';" >> config.default.js
npm init
npm i egg egg-bin
修改package.json,添加script:"dev": "egg-bin dev"
npm run dev
- 此时访问出现404,接下来你还需要添加路由,实现控制器,提供服务,验证,缓存,权限认证等等,我这里简单写个
hello world
。
- router.js
module.exports = app => {
const { router, controller } = app;
router.get('/', controller.app.home);
};
- app/controller/app.js
const { Controller } = require('egg');
class AppController extends Controller {
async home() {
this.ctx.body = 'hello world';
}
}
module.exports = AppController;
- 访问
http://127.0.0.1:7001
页面输出hello world
。 - 注意:推荐使用
TypeScript
或者ESLint
代码检测打开ES6 Module
,你就可以不用在每个文件中加上use strict
了。
3. 编写一个 REST
风格的Resource API
:users
- 路由文件添加一行:
router.resources('users', '/v1/users', 'users');
- 新建文件:
app/controller/users.js
,users
控制器内容如下:const { Controller } = require('egg'); class UsersController extends Controller { async create() { const { ctx } = this; this.ctx.body = '创建'; } async destroy() { const { ctx } = this; this.ctx.body = '删除'; } async update() { const { ctx } = this; this.ctx.body = '修改'; } async show() { const { ctx } = this; this.ctx.body = '查询'; } async index() { const { ctx } = this; this.ctx.body = '列表'; } async new() { const { ctx } = this; this.ctx.body = '创建页面'; } async edit() { const { ctx } = this; this.ctx.body = '修改页面'; } } module.exports = UsersController;
- 使用接口测试工具
postman
测试users RESTful
接口,别说你特么连RESTFul API
风格的接口定义规则都不知道!。 - 测试后发现,
POST
,PUT
,DELETE
接口均无法访问,控制台输出提示:invalid csrf token
。通常有两种CSRF
报错:- missing csrf token
- invalid csrf token
- 这是因为默认的
egg-security
插件对以上三种非安全方法
进行了CSRF
校验。解决办法是在config.default.js
中关闭校验,这时候我们模仿脚手架的做法统一使用config
变量控制导出默认配置文件。- image.png
- 注意:这种解决办法并不优雅也不安全,
CSRF
利用用户同时打开多个网页的时候获取浏览器cookie
,伪造钓鱼进行目标站点的攻击和拿数据。我们暂时关闭校验,验证可以成功。
4. 其他代码规范相关问题
- 编码流程:写路由,写对应控制器层,写对应服务层。
- 控制器层编码流程:验证参数,调用服务层,返回数据。
- 服务层编码流程:访问持久化层,获取数据,返回格式化数据
- 控制器,服务都是需要被对应协商单元测试用例滴,要达到100%覆盖率哦。
文件名和文件夹名都尽量小写,采用REST
风格的话尽量使用复数,但是服务层的类名使用单数,规范哦。 - 重复性代码要么配置化,要么封装为函数调用,尽量让每个文件不要杂糅太多信息。
- 尽量使用
TypeScript
或者ESLint
规范团队代码风格,使用git + pre-commit
效果很不错哦。 -
egg
项目开发请多参考egg-example
开源项目,真的并不难哦。 - 后续再写写
egg
插件的使用和调试,部署相关应用。