欸 敌人们好啊
我是前端工作者 B 老师
刚刚有个前端小朋友问我,B 老师产生什么事了?
我说怎么回事? 给我发了几张截图, 我一看
哦!
原来是昨天有几个小朋友在问 egg.js 怎么应用
他说要和我试试, 我说能够
传统功夫是讲化劲儿的, 四两拨千斤
二百多斤的英国大力士, 都握不动我这一个手指
欸
我一说他啪一下就站起来了, 很快啊
而后上来就是, 一个左正蹬, 一个右鞭腿, 一个左刺拳
我全副没防进来, 被打当前天然是一起学习 egg.js(局部内容来自 egg.js 官网)
我应用 TypeScript 创立 egg.js
TypeScript
TypeScript 是 JavaScript 类型的超集,它能够编译成纯 JavaScript。
此前应用 TypeScript 开发 Egg,会遇到一些影响 开发者体验 问题:
- Egg 最精华的 Loader 主动加载机制,导致 TS 无奈动态剖析出局部依赖。
- Config 主动合并机制下,如何在
config.{env}.js
外面批改插件提供的配置时,能校验并智能提醒? - 开发期须要独立开一个
tsc -w
独立过程来构建代码,带来临时文件地位纠结以及npm scripts
复杂化。 - 单元测试,覆盖率测试,线上谬误堆栈如何指向 TS 源文件,而不是编译后的 js 文件。
环境筹备
- 操作系统:反对 macOS,Linux,Windows
- 运行环境:倡议抉择 LTS 版本,最低要求 8.x。
疾速入门
通过骨架疾速初始化:
$ mkdir showcase && cd showcase
$ npm init egg –type=ts
$ npm i
$ npm run dev
目录标准
一些束缚:
- Egg 目前没有打算应用 TS 重写。
- Egg 以及它对应的插件,会提供对应的
index.d.ts
文件不便开发者应用。 - TypeScript 只是其中一种社区实际,咱们通过工具链给予肯定水平的反对。
- TypeScript 最低要求:版本 2.8。
整体目录构造上跟 Egg 一般我的项目没啥区别:
typescript
代码格调,后缀名为ts
typings
目录用于搁置d.ts
文件(大部分会主动生成)
showcase
├── app
│ ├── controller
│ │ └── home.ts
│ ├── service
│ │ └── news.ts
│ └── router.ts
├── config
│ ├── config.default.ts
│ ├── config.local.ts
│ ├── config.prod.ts
│ └── plugin.ts
├── test
│ └── */.test.ts
├── typings
│ └── */.d.ts
├── README.md
├── package.json
├── tsconfig.json
└── tslint.json
配置(Config)
Config
这块略微有点简单,因为要反对:
- 在 Controller,Service 那边应用配置,需反对多级提醒,并主动关联。
- Config 外部,
config.view = {}
的写法,也应该反对提醒。 - 在
config.{env}.ts
里能够用到config.default.ts
自定义配置的提醒。
import {EggAppConfig, EggAppInfo, PowerPartial} from "egg";
export default (appInfo: EggAppInfo) => {const config = {} as PowerPartial<EggAppConfig>;
// override config from framework / plugin
// use for cookie sign key, should change to your own and keep security
config.keys = appInfo.name + "_1606967424562_9661";
// add your egg config in here
config.middleware = [];
// add your special config in here
const bizConfig = {sourceUrl: `https://github.com/eggjs/examples/tree/master/${appInfo.name}`,
};
// 连贯服务器
config.mysql = {
//database configuration
// 单个数据源 client
// 多个数据源 clients
clients: {
db1: {
//host
host: "localhost",
//port
port: "3306",
//username
user: "root",
//password
password: "root",
//database
database: "egg",
},
db2: {
//host
host: "localhost",
//port
port: "3306",
//username
user: "root",
//password
password: "root",
//database
database: "hubeiwh",
},
},
// 所有数据库配置的默认值
default: {},
//load into app,default is open // 加载到应用程序,默认为关上
app: true,
//load into agent,default is close // 加载到代理中,默认值为“敞开”agent: false,
};
// the return config will combines to EggAppConfig
return {
...config,
...bizConfig,
};
};
控制器(Controller)
// app/controller/home.ts
import {Controller} from "egg";
export default class HomeController extends Controller {public async index() {const { ctx} = this;
ctx.body = await ctx.service.test.sayHi("egg");
}
public async user() {const { ctx} = this;
ctx.body = await ctx.service.test.hello("locker");
}
/**
* 通过 name 字段查问 egg 库外面 username 表查问用户信息
*/
public async name() {const { ctx} = this;
const {name} =ctx.query;
try {const user = await ctx.service.test.name(name);
ctx.body = {
code: 200,
data: user,
message: "success",
};
} catch (e) {
ctx.body = {
code: 500,
data: `user:${e}`,
message: "error",
};
}
}
/**
* 通过 entPid 字段查问 hubeiwh 库外面 cim_enterprise 表查问用户信息
*/
public async ent() {const { ctx} = this;
const {entPid} =ctx.query;
try {const res = await ctx.service.test.entprise(entPid);
ctx.body = {
code: 200,
data: res,
message: "success",
};
} catch (e) {
ctx.body = {
code: 500,
data: `user:${e}`,
message: "error",
};
}
}
}
路由(Router)
// app/router.ts
import {Application} from 'egg';
export default (app: Application) => {const { controller, router} = app;
router.get('/', controller.home.index);
router.get('/user', controller.home.user);
router.get('/name',controller.home.name);
router.get('/ent',controller.home.ent);
};
服务(Service)
// app/service/news.ts
import {Service} from "egg";
/**
* Test Service
*/
export default class Test extends Service {
/**
* sayHi to you
* @param name - your name
*/
public async sayHi(name: string) {return `hi, ${name}`;
}
public async hello(name: string) {return ` 你好, ${name}`;
}
/**
* 查问 egg 库外面 username 表
* @param {string} name 用户名称
*/
public async name(name: string) {
const data: any = await this.app.mysql
// 应用 db1 数据库查问
.get("db1")
.query(`SELECT * FROM USERNAME WHERE name = '${name}'`);
return {data};
}
/**
* 查问 hubeiwh 库外面 username 表
* @param {number} entPid 企业 id
*/
public async entprise(entPid: number) {
const data: any = await this.app.mysql
// 应用 db2 数据库查问
.get("db2")
.get("cim_enterprise", { enterpid: entPid});
return {data};
}
}
```