1. Egg.js安装
1.1 安装Egg.js
cnpm install egg-init -g
采用全局安装,而非--save,原因有待后面分解。
1.2 在VS Code下安装Egg.js代码提示
2. 初始化Egg.js项目
egg-init project_name
如果这样输入命令,则在命令运行过程中会出现一个选项,让你选择所要创建的项目类型:
这里我选择新建一个simple项目,安装完成后,会弹出安装依赖和启动项目的提示命令:
这里要注意,创建项目的是新建一个文件夹。所以请合理的安排安装目录。
已经学到Egg.js了,各种cnpm的命令是什么意思应该很清楚了吧?
所以接下来安装依赖:
cnpm install
安装完成后,启动项目:
npm run dev
3. Egg.js目录约定
3.1 官方约定。
egg-project
├── package.json
├── app.js (可选)
├── agent.js (可选)
├── app
| ├── router.js
│ ├── controller
│ | └── home.js
│ ├── service (可选)
│ | └── 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
3.2 MVC架构
我们的开发都在app目录下完成,Egg.js使用MVC架构,与文件夹对应关系如下:
├── app
| ├── router.js(路由规则)
│ ├── controller(Controller)
│ | └── home.js
│ ├── service (Model)
│ | └── user.js
│ ├── middleware (中间件)
│ | └── response_time.js
│ ├── public (静态资源)
│ | └── reset.css
│ ├── view (View)
│ | └── home.tpl
│ └── extend (扩展方法)
│ ├── helper.js (可选)
│ ├── request.js (可选)
│ ├── response.js (可选)
│ ├── context.js (可选)
│ ├── application.js (可选)
│ └── agent.js (可选)
4. 一个mini的Egg.js项目
4.1 安装egg-view-ejs插件
cnpm install ejs --save
cnpm install egg-view-ejs --save
安装插件后需要配置两个文件:
文件1:/config/plugin.js
'use strict';
/** @type Egg.EggPlugin */
module.exports = {
// had enabled by egg
// static: {
// enable: true,
// }
ejs:{//增加部分
enable: true,
package: 'egg-view-ejs',
}
};
文件2:/config/config.default.js
/* eslint valid-jsdoc: "off" */
'use strict';
/**
* @param {Egg.EggAppInfo} appInfo app info
*/
module.exports = appInfo => {
/**
* built-in config
* @type {Egg.EggAppConfig}
**/
const config = exports = {};
// use for cookie sign key, should change to your own and keep security
config.keys = appInfo.name + '_1582681748898_3732';
// add your middleware config here
config.middleware = [];
// add your user config here
const userConfig = {
// myAppName: 'egg',
};
config.view = {//增加部分
mapping: {
'.html': 'ejs',
},
};
return {
...config,
...userConfig,
};
};
4.2 文件结构
├── app
| ├── router.js
│ ├── controller
│ | └── news.js
│ ├── service
│ | └── news.js
│ ├── public
│ └── images
│ └── welcome.gif
│ ├── view
│ └── index.html
│ └── content.html
│ └── list.html
4.3 文件代码
4.3.1 router.js
'use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const { router, controller } = app;
router.get('/', controller.news.index);
router.get('/list', controller.news.list);
router.get('/content/:newsid/:newscategory', controller.news.content);
};
4.3.2 service/news.js 模拟从数据库获取并返回数据
'use strict';
const Service = require("egg").Service;
class NewsService extends Service {
async getNewsList(){
//模拟从数据库模拟数据
var dbData = ["A news about Tom","Jerry's news is cooler!","Popeye finally married Olive!"];
return dbData;
}
}
module.exports = NewsService;
4.3.3 controller/news.js 处理业务逻辑
'use strict';
const Controller = require('egg').Controller;
class NewsController extends Controller {
async index() {
const { ctx } = this;
await ctx.render("index.html");
}
async list() {
const { ctx } = this;
var newsList = await ctx.service.news.getNewsList();
await ctx.render("list.html",{
newsList:newsList
});
}
async content() {
const { ctx } = this;
var getInfo = ctx.query;
var paraInfo = ctx.params;
var name = getInfo.name;
var level = getInfo.level;
var newsId = paraInfo["newsid"];
var newsCategory = paraInfo["newscategory"];
await ctx.render("content.html",{
name:name,
level:level,
newsid:newsId,
newscategory:newsCategory
});
}
}
module.exports = NewsController;
4.3.4 view/三个文件
文件1:view/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>你好!欢迎进入迷你新闻系统!</h1>
<h2>在Egg.js中,静态资源直接使用资源目录路径引用即可!比如下面的图片</h2>
<img src="/public/images/welcome.gif" >
<h3><a href="/list">点我进入新闻列表</a></h3>
</body>
</html>
文件2:view/list.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>新闻列表</h1>
<ul>
<%for(let i=0;i<newsList.length;i++){%>
<li><%=newsList[i]%></li>
<%}%>
</ul>
<h3>
<a href="/content/6/HotNews?name=Tom&level=3">
这条新闻通过参数和动态路由传递数据,链接地址是: /content/6/HotNews?name=Tom&level=3
</a>
</h3>
</body>
</html>
文件3:view/content.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h3>Name is: <%=name%></h3>
<h3>Level is: <%=level%></h3>
<h3>News ID is: <%=newsid%></h3>
<h3>News Category is: <%=newscategory%></h3>
</body>
</html>