New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] TypeScript tool support #2272

Closed
atian25 opened this Issue Mar 26, 2018 · 35 comments

Comments

Projects
None yet
@atian25
Copy link
Member

atian25 commented Mar 26, 2018

背景

当前使用 TypeScript 开发 Egg ,会面临的影响开发者体验问题:

  • Egg 最精髓的 Loader 自动加载机制,导致 TS 无法静态分析出部分依赖,譬如 app/service/news.ts 会自动挂载为 ctx.service.news
  • Egg 的 Config 自动合并机制下,如何在 config.{env}.js 里面修改插件提供的配置时,能校验并智能提示?
  • 开发期需要独立开一个 tsc -w 独立进程来构建代码,带来临时文件位置纠结以及 npm scripts 复杂化。
  • 单元测试,覆盖率测试,线上错误堆栈如何指向 TS 源文件,而不是编译后的 js 文件。

思路

  • 约束
    • Egg 目前没有计划使用 TS 重写。
    • Egg 以及它对应的插件,提供对应的 index.d.ts 文件方便开发者使用。
  • 通过 TS 的 Declaration Merging 编写 d.ts 来辅助定位。
  • 使用 TS 2.8 提供的 Conditional Types 黑魔法。
  • 通过工具链方面的支持,在开发期无需编译 TS
    • egg loader 支持开发期加载 ts 文件
    • egg-bin 等工具支持 sourcemap 和 ts-node
  • 同样需引入工具链映射 sourcemap

事项

后续

以下内容不属于本期内容,仅做备忘,后续跟进

@popomore popomore changed the title [RFC] Typescript support [RFC] Typescript tool support Mar 27, 2018

@atian25 atian25 changed the title [RFC] Typescript tool support [RFC] TypeScript tool support Mar 27, 2018

@atian25

This comment has been minimized.

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Mar 28, 2018

ts-node 锁版本的,tsc 版本不匹配,可能有坑。。。

@popomore

This comment has been minimized.

Copy link
Member

popomore commented Mar 28, 2018

egg-bin 提供一个使用 ts-node 的 tsc?我还不清楚具体差异。

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Mar 28, 2018

egg-bin 提供一个使用 ts-node 的 tsc?我还不清楚具体差异。

@popomore 具体指?

我想的是,fork 一个 ts-node 然后去掉它的 lock,这样可以直接用 tsc 的最新版

@whxaxes

This comment has been minimized.

Copy link
Member

whxaxes commented Mar 28, 2018

我在想,ts 的那些拓展能力没有写到官方文档里的,只是写在了 wiki 中,是不是意味着不是稳定的,我觉得 ts-node 的作者是不是担心 ts 某个版本突然把某个 api 改掉了,就 break 了,所以才把版本给锁了

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Mar 28, 2018

但起码要更新吧。 或者提个 PR 帮他把 lock 更新到最新吧

其实我觉得更有可能是他升级了 npm5 后,无意识的加了 package-lock

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Mar 28, 2018

看错了。。。 ts-node 没有带 tsc 的,那是 dev dep。

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Apr 1, 2018

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Apr 4, 2018

更新正文,补充背景和思路

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Apr 4, 2018

  • PowerPartial,EggPlugin,EnvType 下沉到 egg,合并到那个 PR
  • 编写插件开发指南
  • 更新 example
  • Middleware Options
  • ets 支持 import plugin
  • ets 支持检查同名文件并提醒
  • 编写 TS 踩坑折腾史
@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 4, 2018

  • test 用例是否支持直接运行 .ts 文件。如果用 ts-node 直接跑用例,那么问题是就无法使用不同类型的参数来测试接口了
@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Apr 4, 2018

@waitingsong 没看懂, egg-bin test --grep=

@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 5, 2018

@atian25 egg-bin test --grep= 这个没看懂

我的意思是假如有模块函数

function add(a: number, b: number): number {
  return a + b;
}

如果基于 TS 开发,那么不用检查 a/b 的类型。并且在用 TS 写的测试用例里面也无法测试非数字类型参数情况

it('should add workds', () => {
  assert(add('1', 2) === 3)  // <----- VSC 会直接报类型错误的
})

但是假如存在调用模块的开发语言不是 TS 的情况,那么就需要在 add() 函数内做类型检查或者转换。那么产生 if/else 分支在跑 cov 里面就会有 missing 。于是又只有加上忽略注释

/* istanbul ignore next */
/* istanbul ignore if  */
/* istanbul ignore else  */

挺头疼的……

@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 6, 2018

有个问题:
如果 tsconfig.json 中设置 "declaration": true 那么提示错误

config/config.local.ts:5:1 - error TS4082: Default export of the module has or is using private name 'PowerPartial'.

5 export default () => {
~
6 const config = <DefaultConfig> {}
~
...
12 return config
~
13 }

貌似是 PowerPartial 引发,设置 declaration 为 false 就不报错。
看起来貌似 PowerPartial 这个接口没有 export 导致的,不过我已经修改了 node_modules/egg/index.d.ts 导出了的啊?

@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 6, 2018

如果把 config.default.ts 文件的

// for config.{env}.ts
export type DefaultConfig = PowerPartial<EggAppConfig & BizConfig>

改成

export type DefaultConfig = EggAppConfig & BizConfig

就不会有上面的错误。

@whxaxes

This comment has been minimized.

Copy link
Member

whxaxes commented Apr 6, 2018

@waitingsong 感觉不像是 declaration 的问题?我本机试了一下设置 declaretion 为 true,没有出现你所述的错误,提供个稳定复现的项目看看?

@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 6, 2018

我是在 egg-example/hacknews-async-ts 这个目录里面遇到这个问题的

@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 6, 2018

是基于那个例子修改后遇到的。等我今天确认下复现

@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 7, 2018

@whxaxes
https://github.com/eggjs/examples 目录 hackernews-async-ts , 修改 tsconfig.json 添加 "declaration": true, 就能复现了

@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 7, 2018

最小复现代码

config.default.ts

export interface Config {
  keys: string
  news: {
    pageSize: number;
  };
}

export type PowerPartial<T> = {
  [U in keyof T]?: T[U] extends {}
  ? PowerPartial<T[U]>
  : T[U]
}

// for config.{env}.ts
export type DefaultConfig = PowerPartial<Config>;

config.local.ts

import { DefaultConfig } from './config.default';

export default () => {
  const config: DefaultConfig = {};

  config.keys = 'foo'

  return config;
};
@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 7, 2018

如果把

export interface Config {
  keys: string
  news: {
    pageSize: number;
  };
}

删除 news 对象为

export interface Config {
  keys: string
 // news: {
  //  pageSize: number;
  // };
}

就没问题

@waitingsong

This comment has been minimized.

Copy link
Contributor

waitingsong commented Apr 7, 2018

如果把 config.local.ts 的内容复制到 config.default.ts 然后删除 config.local.ts,也不会报错

@shangyu95

This comment has been minimized.

Copy link

shangyu95 commented Apr 8, 2018

@atian25 ts模板的schedule无法使用啊

@duncup

This comment has been minimized.

Copy link

duncup commented Apr 8, 2018

@lindraco 可以用,我已经在用了。
先安装@types/sequelize

//typings/index.d.ts
import Sequelize from 'sequelize';

declare module 'egg' {

  // 扩展 app
  interface Application {
    Sequelize: Sequelize;
    model: Sequelize.Sequelize;
  }

  // 扩展 context
  interface Context {
    Sequelize: Sequelize;
    model: Sequelize.Sequelize;
  }

  // 扩展你的配置
  interface EggAppConfig {
    sequelize: {
      dialect: string;
      database: string;
      host: string;
      port: string;
      username: string;
      password: string;
    };
  }

}

简单点的话也可以用any

@atian25 顺便求审pr https://github.com/eggjs/egg-sequelize/#47

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Apr 12, 2018

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Apr 12, 2018

这个 RFC 可以关了, tegg 那边回头 @popomore 另起

@atian25 atian25 closed this Apr 12, 2018

@popomore

This comment has been minimized.

Copy link
Member

popomore commented Apr 12, 2018

@4tj

This comment has been minimized.

Copy link

4tj commented Apr 21, 2018

@shangyu95 sequelize、mongo也无法使用,egg-ts-helper只监听了固定的4个目录 🤥

@isLishude

This comment has been minimized.

Copy link

isLishude commented Jun 2, 2018

上次看到死马的采访说egg不会使用ts重写,tegg 使用 ts 重写版本么?

@ngot

This comment has been minimized.

Copy link
Member

ngot commented Jun 2, 2018

不会用Ts重写egg内核,没有意义。

@atian25

This comment has been minimized.

Copy link
Member Author

atian25 commented Jun 2, 2018

不会,tegg 只是一个上层框架。

Egg 至少一年内没有重写的计划,没有什么特别的好处。

@whxaxes

This comment has been minimized.

Copy link
Member

whxaxes commented Dec 27, 2018

@yaonote 入口文件?说说你遇到的问题吧

@yaonote

This comment has been minimized.

Copy link

yaonote commented Dec 27, 2018

@yaonote 入口文件?说说你遇到的问题吧

理解了,打扰了~~~~~~

@unclexiao

This comment has been minimized.

Copy link

unclexiao commented Jan 8, 2019

为什么tegg仓库是空的,ts改造计划搁浅了么?

@whxaxes

This comment has been minimized.

Copy link
Member

whxaxes commented Jan 8, 2019

@unclexiao 没有搁浅,目前 egg 已经可以使用 ts 了,tegg 只是一个依赖注入方案的 egg 上层封装框架,目前还没空做而已。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment