Egg是对koa做加法
> npm init egg --type=simple
npx: 397 安装成功,用时 14.809 秒
[egg-init] use registry: https://registry.npmjs.org
? Please enter target dir:
? project name Demo
? project description
? project author
? cookie security keys 1598957364445_5820
目录结构
├── app
│ ├── controller // controller们
│ │ └── home.js
│ ├── public // 静态资源
│ └── router.js // 路由
├── config
│ └── config.default.js // 项目配置
└── package.json
reader view
npm i egg-view-nunjucks --save
// config/plugin.js
nunjucks: {
enable: true,
package: 'egg-view-nunjucks',
},
// config.default.js
view: {
defaultViewEngine: 'nunjucks',
mapping: {
'.tpl': 'nunjucks',
},
}
// router.js
module.exports = app => {
const { router, controller } = app;
router.get('/news', controller.home.news);
router.get('/', controller.home.index);
};
// controller/home.js
async news() {
const dataList = {
list: [
{ id: 1, title: 'this is news 1', url: '/news/1' },
{ id: 2, title: 'this is news 2', url: '/news/2' },
],
};
await this.ctx.render('home.tpl', dataList);
}
// view/home.tpl
<html>
<head>
<title>News</title>
</head>
<body>
<ul class="news-view view">
{% for item in list %}
<li class="item">
<a href="{{ item.url }}">{{ item.title }}</a>
</li>
{% endfor %}
</ul>
</body>
</html>
模板必须放在view下,否则找不到。
服务(数据请求)
egg框架封装了网络请求和db访问,分别在对象 ctx.db 和 ctx.curl上。
// service/news.js
const Service = require('egg').Service;
class NewsService extends Service {
async list() {
const url = 'https://...';
// use build-in http client to GET hacker-news api
const { data } = await this.ctx.curl(url, { dataType: 'json' });
// 可以通过 config 对象访问 config/config.default.js 里的数据
console.log('[[[[[[[', this.config.API, data);
return data;
}
}
module.exports = NewsService;
// controller/home.js
async news() {
const dataList = await this.service.news.list();
await this.ctx.render('home.tpl', { list: dataList.result });
}
扩展(filter?) extend
// extend/helper.js
exports.markurl = id => `http://127.0.0.1:7001/news/${id}`;
// view/home.tpl
<a href="{{ helper.markurl(item.id) }}">{{ item.title }}</a>
中间件 Middleware
// config.default.js
config.middleware = [ 'gzip' ];
config.gzip = { threshold: 1024 }; // 小于 1k 的响应体不压缩
// middleware/gzip.js
const zlib = require('zlib');
module.exports = options => {
return async function gzip(ctx, next) {
await next();
// 后续中间件执行完成后将响应体转换成 gzip
let body = ctx.body;
if (!body) return;
// 支持 options.threshold
if (options.threshold && ctx.length < options.threshold) return;
console.log('-----optins', options, ctx.length, typeof body);
if (typeof body === 'object') body = JSON.stringify(body);
// 设置 gzip body,修正响应头
const stream = zlib.createGzip();
stream.end(body);
ctx.body = stream;
ctx.set('Content-Encoding', 'gzip');
};
};
最后,再来看一下目录结构
├── app
│ ├── controller // controller们
│ │ └── home.js
│ ├── extend // 扩展
│ ├── middleware // 中间件
│ ├── public // 静态资源
│ └── service // 服务、接口(网络请求、db查询)
│ └── router.js // 路由
├── config
│ └── config.default.js // 项目配置
└── package.json
网友评论