本文最后更新于 46 天前,其中的信息可能已经有所发展或是发生改变。
🎯 本文能带给你什么?
+ 1小时掌握Egg.js核心开发能力
+ 10个前端最关心的实战场景解析
+ 6大企业级最佳实践方案
+ 3种调试技巧快速定位问题
🛠️ 环境配置(3分钟搞定)
1. 环境要求
# 查看Node版本(建议16.x LTS)
$ node -v
v16.14.2
# 国内用户推荐
$ npm config set registry https://registry.npmmirror.com
$ npm install -g cnpm
2. 项目初始化
# 创建项目(选择simple模板)
$ npm init egg --type=simple --force
$ cd egg-example
$ cnpm install
3. 目录结构解析
app/
├── router.js ➡️ 路由配置(类比前端路由)
├── controller/ ➡️ 业务逻辑处理层
├── service/ ➡️ 数据服务抽象层
config/
├── plugin.js ➡️ 插件配置中心
└── config.default.js ➡️ 主配置文件
🔥 核心开发四部曲
1. 创建首个RESTful API
// app/router.js
module.exports = app => {
const { router, controller } = app;
router.resources('users', '/api/users', controller.users);
};
// app/controller/users.js
const Controller = require('egg').Controller;
class UserController extends Controller {
// GET /api/users
async index() {
const users = await this.service.user.list();
this.ctx.success(users); // 封装响应格式
}
}
2. 服务层开发
// app/service/user.js
const Service = require('egg').Service;
class UserService extends Service {
async list() {
return this.ctx.model.User.findAll({
attributes: ['id', 'name', 'avatar']
});
}
}
3. 统一响应处理
// app/extend/context.js
module.exports = {
success(data) {
this.body = {
code: 0,
data,
timestamp: Date.now()
};
}
};
4. 启动与测试
bashCopy Code$ npm run dev
# 测试地址 → http://localhost:7001/api/users
🎨 前端最关心的三大场景
场景1:静态资源托管
// config/config.default.js
exports.static = {
prefix: '/public',
dir: [
path.join(appInfo.baseDir, 'app/public'), // 前端构建产物
path.join(appInfo.baseDir, 'uploads') // 上传文件目录
]
};
bashCopy Code# 推荐目录结构
app/public/
├── css/
├── js/
└── images/
场景2:服务端渲染(SSR)
// 安装模板引擎
$ cnpm i egg-view-nunjucks
// 控制器中使用
async render() {
await this.ctx.render('page.njk', {
title: '商品详情页',
data: await this.service.product.getDetail()
});
}
nunjucksCopy Code{# app/view/page.njk #}
<html>
<body>
<div id="root">{{ data | safe }}</div>
<script src="/public/js/ssr-entry.js"></script>
</body>
</html>
场景3:接口文档自动化
// 配置swagger插件
exports.swaggerdoc = {
enable: true,
package: 'egg-swagger-doc',
};
/**
* @Controller /api/products
*/
class ProductController extends Controller {
/**
* @Summary 获取商品列表
* @Router GET /api/products
* @Request query integer pageNo
* @Response 200 productList
*/
async list() {
// ...
}
}
🛡️ 企业级最佳实践
1. 安全防护配置
// config/config.default.js
exports.security = {
csrf: {
ignore: ctx => ctx.is('json') || ctx.path.startsWith('/api/')
},
csp: {
policy: {
'default-src': "'self'",
'script-src': ["'self'", 'unpkg.com']
}
}
};
2. 异常监控方案
// app/middleware/error_handler.js
module.exports = () => {
return async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.app.emit('error', err, ctx);
ctx.fail(err.message); // 统一错误响应
}
};
};
🚀 性能优化矩阵
优化维度 | 具体方案 | 效果预估 |
---|---|---|
接口缓存 | Redis+内存双缓存策略 | QPS提升5-10倍 |
集群部署 | egg-scripts + PM2集群模式 | 吞吐量提升300% |
数据库优化 | Sequelize连接池+慢查询监控 | 查询耗时降低60% |
编译优化 | Webpack DLL+多进程编译 | 构建速度提升70% |
🔧 调试技巧大全
技巧1:VSCode断点调试
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Egg",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "debug"],
"port": 9229,
"console": "integratedTerminal"
}
]
}
技巧2:请求链路追踪
// app/middleware/trace.js
module.exports = () => {
return async (ctx, next) => {
const traceId = ctx.get('X-Trace-Id') || uuid.v4();
ctx.tracer = {
traceId,
userId: ctx.session.userId
};
await next();
ctx.set('X-Trace-Id', traceId);
};
};
注意:生产环境务必配置Nginx反向代理和HTTPS
+ 推荐:使用阿里云ECS部署可获得最佳兼容性