入门egg.js

Killerbee

欸 朋友们好啊
我是前端工作者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 };
 }
}
​```

阅读 160
3 声望
0 粉丝
0 条评论
3 声望
0 粉丝
宣传栏