Open atian25 opened 6 years ago
在docker中开发时, egg-bin dev -r egg-ts-helper/register
和 npm run dev
在编辑器(vs code)保存 .ts文件后进程没有自动重启,意思是需要手动重启后才能看到.ts文件改动后的运行效果。
参照文档 https://eggjs.org/zh-cn/basics/schedule.html ,
import { Subscription } from 'egg'; // [ts] Module ''egg'' has no exported member 'Subscription'.
npm run dev tsc
编译也失败
第一个问题,是 egg-watcher 那块,似乎在 docker 里面是拿不到 node 的 watch 事件的,加个 https://github.com/eggjs/egg-watcher-chokidar 看看。
第二个问题,Subscription 这个是漏了,已经有人提了 PR: https://github.com/eggjs/egg/pull/2321 ,等 merged 后就可以了
在Linux 环境中、使用这个脚手架生成项目结构出现一个权限的问题,像config service 等文件是root的权限,普通用户不能对这些文件进行操作, 而不使用这个脚手架来搭项目结构,在import egg 这个module的时候,会出现[ts] Cannot find module 'egg'. 在ts 中使用import * as Egg from 'egg'; 这种方式引入
这属于 linux 的权限问题,自己看下 linux 相关资料吧。估计你是用 root 执行的 egg-init
使用pnpm安装后执行npm run dev报错,default的plugin路径会出问题,找不到egg-onerror等基础plugin,建议可以修复一下egg-core的plugin.js的路径解析的机制,支持一下pnpm
我们日常用的 cnpm 的底层是 cnpm/npminstall,包路径跟 pnpm 应该是一致的才对,提供下可复现方案吧。
cc @whxaxes
D:\code\npm\login\node_modules\.registry.npm.taobao.org\egg-core\4.12.0\node_modules\egg-core\lib\loader\mixin\plugin.js:356 throw new Error(
Can not find plugin ${name} in "${lookupDirs.join(', ')}"); ^ Error: Can not find plugin egg-onerror in "D:\code\npm\login\node_modules, D:\code\npm\login\node_modules\.registry.npm.taobao.org\egg\2.14.1\node_modules\egg\node_modules, D:\code\npm\login\node_modules"
path中缺少了D:\code\npm\login\node_modules.registry.npm.taobao.org\egg\2.14.1\node_modules
@atian25
提供个最小可复现仓库
前言
TypeScript 的静态类型检查,智能提示,IDE 友好性等特性,对于大规模企业级应用,是非常的有价值的。详见:TypeScript体系调研报告 。
然而,此前使用 TypeScript 开发 Egg ,会遇到一些影响 开发者体验 问题:
config.{env}.js
里面修改插件提供的配置时,能校验并智能提示?tsc -w
独立进程来构建代码,带来临时文件位置纠结以及npm scripts
复杂化。本文主要阐述:
具体的折腾过程参见:[RFC] TypeScript tool support
快速入门
通过骨架快速初始化:
上述骨架会生成一个极简版的示例,更完整的示例参见:eggjs/examples/hackernews-async-ts
目录规范
一些约束:
index.d.ts
文件方便开发者使用。整体目录结构上跟 Egg 普通项目没啥区别:
typescript
代码风格,后缀名为ts
typings
目录用于放置d.ts
文件(大部分会自动生成)Controller
Router
Service
Middleware
因为 Middleware 定义是支持入参的,第一个参数为同名的 Config,如有需求,可以用完整版:
Extend
Config
Config
这块稍微有点复杂,因为要支持:config.view = {}
的写法,也应该支持提示。config.{env}.ts
里可以用到config.default.ts
自定义配置的提示。简单版:
备注:
Conditional Types
是我们能完美解决 Config 提示的关键。PowerPartial
实现。Plugin
Typings
该目录为 TS 的规范,在里面的
\*\*/\*.d.ts
文件将被自动识别。typings/index.d.ts
中。typings/{app,config}/\*\*.d.ts
,请勿自行修改,避免被覆盖。(见下文)开发期
ts-node
egg-bin
已经内建了 ts-node ,egg loader
在开发期会自动加载\*.ts
并内存编译。目前已支持
dev
/debug
/test
/cov
。开发者仅需简单配置下
package.json
:egg-ts-helper
由于 Egg 的自动加载机制,导致 TS 无法静态分析依赖,关联提示。
幸亏 TS 黑魔法比较多,我们可以通过 TS 的 Declaration Merging 编写
d.ts
来辅助。譬如
app/service/news.ts
会自动挂载为ctx.service.news
,通过如下写法即识别到:手动写这些文件,未免有点繁琐,因此我们提供了 egg-ts-helper 工具来自动分析源码生成对应的
d.ts
文件。只需配置下
package.json
:开发期将自动生成对应的
d.ts
到typings/{app,config}/
下,请勿自行修改,避免被覆盖。Unit Test && Cov
单元测试当然少不了:
运行命令也跟之前一样,并内置了
错误堆栈和覆盖率
的支持:Debug
断点调试跟之前也没啥区别,会自动通过
sourcemap
断点到正确的位置。部署
构建
ci
上构建并打包。配置
package.json
:对应的
tsconfig.json
:注意:
egg-ts-helper
会自动调用清除同名的js
文件,也可npm run clean
手动清除。错误堆栈
线上服务的代码是经过编译后的 js,而我们期望看到的错误堆栈是指向 TS 源码。 因此:
inlineSourceMap: true
在 js 底部插入 sourcemap 信息。egg-scripts
内建了处理,会自动纠正为正确的错误堆栈,应用开发者无需担心。具体内幕参见:
插件/框架开发指南
指导原则:
index.d.ts
。egg
这个 module,不要用上层框架。插件
可以参考
egg-ts-helper
自动生成的格式上层框架
定义:
开发者使用的时候,可以直接 import 你的框架:
其他
TypeScript
最低要求 2.8+ 版本,依赖于新支持的 Conditional Types ,黑魔法中的黑魔法。
VSCode
由于 VSCode 自带的 TypeScript 版本还未更新,需手动切换:
之前为了不显示编译后的 js 文件,会配置
.vscode/settings.json
,但由于我们开发期已经不再构建 js,且 js 和 ts 同时存在时会优先加载 js,因为 建议「不要」配置此项。package.json
完整的配置如下:
高级用法
装饰器
通过 TS 的装饰器,可以实现
依赖注入
/参数校验
/日志前置处理
等。目前装饰器属于锦上添花,因为暂不做约定。 交给开发者自行实践,期望能看到社区优秀实践反馈,也可以参考下:egg-di 。
tegg
未来可能还会封装一个上层框架 tegg,具体 RFC 还没出,还在孕育中,敬请期待。
名字典故:
typescript + egg
->ts-egg
->tea egg
->茶叶蛋
Logo:
写在最后
早在一年多前,阿里内部就有很多 BU 在实践 TS + Egg 了。
随着 TS 的完善,终于能完美解决我们的开发者体验问题,也因此才有了本文。
本来以为只需要 2 个 PR 搞定的,结果变为 Hail Hydra,好长的 List:[RFC] TypeScript tool support 。
终于完成了 Egg 2.0 发布时的一大承诺,希望能通过这套最佳实践规范,提升社区开发者的研发体验。