初始化模板
使用官方脚手架生成基本模板:
$ mkdir egg-demo && cd egg-demo
$ npm init egg
[egg-init] use registry: https://registry.npmjs.org
[egg-init] target dir is /home/barwe/projects/egg-demo
[egg-init] fetching npm info of egg-init-config
? Please select a boilerplate type
──────────────
simple - Simple egg app boilerplate
microservice - Microservice app boilerplate based on egg
sequelize - egg app with sequelize
❯ ts - Simple egg && typescript app boilerplate
empty - Empty egg app boilerplate
plugin - egg plugin boilerplate
framework - egg framework boilerplate
选择 " ts - Simple egg && typescript app boilerplate" 生成 egg-ts 模板。
$ pnpm install
$ pnpm dev
然而直接报错了。
控制器实例找不到 ctx
默认生成的代码是这样的:
import { Controller } from "egg";
export default class HomeController extends Controller {
public async index() {
const { ctx } = this;
ctx.body = await ctx.service.test.sayHi("egg");
}
}
编辑器是能正确识别这个 ctx
属性的:
然而启动服务器时却找不到,但这个属性确实是存在的:
export class BaseContextClass<Context = any, Application = any, EggAppConfig = any, Service = any> {
constructor(ctx: Context);
protected ctx: Context;
protected app: Application;
protected config: EggAppConfig;
protected service: Service;
}
这种情况还会发生在其它地方,例如找不到 Application
对象的 once
属性等。接着看后面的报错,发现它与一个叫 ts-node 的东西相关,就去查了下这个东西,ts-node 是用来执行和交互式运行 ts 代码的工具,还提供了 source map 和原生 ESM 的支持,具体参考:
然而我们的项目并没有安装这个东西,装上它就 OK 了:
$ pnpm add -D ts-node
然后就正常了:
$ pnpm dev
> demo@1.0.0 dev /home/barwe/projects/egg-demo
> egg-bin dev
[egg-ts-helper] create typings/app/controller/index.d.ts (2ms)
[egg-ts-helper] create typings/config/index.d.ts (12ms)
[egg-ts-helper] create typings/config/plugin.d.ts (0ms)
[egg-ts-helper] create typings/app/service/index.d.ts (1ms)
[egg-ts-helper] create typings/app/index.d.ts (1ms)
2022-04-13 00:22:21,068 INFO 6002 [master] node version v14.19.0
2022-04-13 00:22:21,069 INFO 6002 [master] egg version 2.35.0
2022-04-13 00:22:21,803 INFO 6002 [master] agent_worker#1:6053 started (731ms)
2022-04-13 00:22:23,487 INFO 6002 [master] egg started on http://127.0.0.1:7001 (2418ms)
这里还有个坑就是,虽然它提示访问 http://127.0.0.1:7001
,但是这个地址在浏览器中看不到任何东西。
浏览器中需要输入的是 http://localhost:7001/
:
看到这个说明已经可以正常请求了。
集成代码检查工具
然后我们开始集成代码检查工具:prettier + eslint + lintstaged。
eslint
模板已经添加了 eslint 依赖,先升级 eslint:
$ pnpm remove eslint eslint-config-egg
$ pnpm add -D eslint eslint-config-egg
运行配置程序:
$ pnpm eslint --init
? How would you like to use ESLint? To check syntax and find problems
? What type of modules does your project use? JavaScript modules (import/export)
? Which framework does your project use? None of these
? Does your project use TypeScript? Yes
? Where does your code run? Browser
? What format do you want your config file to be in? JavaScript
The config that you've selected requires the following dependencies:
@typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
? Would you like to install them now with npm? No
$ pnpm add -D @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
这将生成新的配置文件 .eslintrc.js,添加规则 'eslint-config-egg/typescript'
到新的配置文件并删除默认的配置文件。
模板的 package.json 中已经定义了相关的脚本:
{ "lint": "eslint . --ext .ts" }
执行 pnpm lint
检查项目的所有 ts 脚本。
prettier
模板默认未集成 prettier。
$ pnpm add -D prettier
新建配置文件:
module.exports = {
printWidth: 80, //单行长度
tabWidth: 4, //缩进长度
useTabs: false, //使用空格代替tab缩进
semi: false, //句末使用分号
singleQuote: true, //使用单引号
trailingComma: 'es5', // 多行时尽可能打印尾随逗号
bracketSpacing: true, // 在对象前后添加空格-eg: { foo: bar }
arrowParens: 'avoid', //单参数箭头函数参数周围使用圆括号-eg: (x) => x
endOfLine: 'lf', //结束行形式
}
新建忽略文件:
.vscode/
logs/
run/
.*ignore
pnpm-lock.yaml
typings/app/
typings/config/
版本控制
在 .gitignore 中加入下面这两行:
!.eslintrc.js
!.prettierrc.js
格式化项目代码
将下列脚本加入 package.json 中:
{ "prettier": "prettier --write './**/*'" }
然后使用下列指令格式化整个项目:
$ pnpm prettier
然而这还没完,我们用 prettier 格式化的代码很可能和 eslint 的规范不兼容。下面解决兼容问题:
$ pnpm add -D eslint-plugin-prettier eslint-config-prettier
然后在 .eslintrc.js 文件中增加 'plugin:prettier/recommended'
规范:
module.exports = {
extends: [
'plugin:prettier/recommended',
],
}
再次执行 pnpm lint
检查代码。
评论区