ts-api-loader
v0.1.0
Published
an awesome ts-api / rc d.ts translator
Downloads
1
Maintainers
Readme
一个接口对接方案
快速了解demo
http://gitlab.alibaba-inc.com/javaer.ljw/api-loader-demo
motivation
- 简化/结构化 web 项目 api 请求代码, 提高团队协作开发和阅读效率, 并为可视化提供可能性
- 运行时自动根据 typescript 类型 mock 数据 (可选是否使用)
- 运行时自动根据 typescript 类型 check 数据(可选是否使用)
- low-code practice
- ~~强迫业务开发人员多写注释, 少给别人挖坑~~
设计文档
https://yuque.antfin-inc.com/recore/api-loader/introduce
例子🌰
import { TIndexCards, TVideoCards, TDemandData, EmbedStruct } from './demo.type';
import * as ajax from '@ali/api-runtime/lib/request/ajax';
const host = process.env.isDev ? 'https://mocks.alibaba-inc.com' : '';
const willFetch = (axiosParam: AxiosRequestConfig) => {
// modify axiosParam. eg axiosParam.header={csrf_token: window.csrf_token}
return axiosParam;
}
/**
* 用电量接口请求组, class 上的注释项/注解项会被method复用
* class 上的注解会被方法继承使用, 即所有方法都会执行该 willFetch
* 更多 ajax 用法参考 https://web.npm.alibaba-inc.com/package/@ali/api-runtime
* @kind ajax
* @host https://mocks.alibaba-inc.com
* @baseUrl /mock/limitless/demo
* @method get
*/
@ajax.willFetch(willFetch) // api-loader^0.7.0开始支持注解, 依赖最新 vscode-recore 插件支持该语法
declare class DemoApi {
/**
* 查询指标看板数据
* @url /indexcards.json
*/
getIndexCards(foo: string, bar: number): Promise<TIndexCards>;
/**
* `@mock注释` 表示该请求自动根据返回的 ts 类型 mock, 不发起真实请求
* @mock true
* @url /videocards.json
*/
@ajax.host(host) // 覆盖 class 注释的 host, 且支持变量
@ajax.willFetch((axiosParam) => {...}) // 覆盖 class 注释的 willFetch
getVideoCards(): Promise<TVideoCards>;
}
基本用法
安装
recore 项目内置,不需要安装步骤
tnpm i --save @ali/api-loader
- 在webpack中添加如下loader, 注意该loader要在 ts-loader 执行之前
{
'test': /(\.api|\.type)\.ts$/, // *.api.ts 和 *.type.ts 需要过 api-loader
'use': [
{
loader: '@ali/api-loader',
options: {
keepComment: false // 是否保留注释
log: false // 是否显示 loader 执行日志
mock: env === 'development' // webpack开发模式下才启用mock
}
}
]
}
- 按照上述例子编写 x.api.ts 文件. (类型声明较多时建议将声明独立到 x.type.ts 文件, 方便业务引用)
进阶使用
上述方式应该基本满足日常 web 项目开发需要, 但如果遇到需要自定义 kind, 例如不用 http request, 想用 fetch 实现, 或者有自己包装的其他协议(如 mqtt/zeromq 等), 则可以通过本节介绍的拓展 kind 方法
自定义 kind
如果不希望使用 @ajax
, 或者想自己不基于 axios 自己写一套请求,可以使用如下方式注册一个 kind:
在工程目录下配置 api.config.js 文件,内容如下
module.exports = {
// 此处注册的 myAjax 后续可以在 *.api.ts 中使用 @kind myAjax
myAjax: './src/request/myAjax',
// 此处注册的 myRequestKind2 后续可以在 *.api.ts 中使用 @kind myRequestKind2
myRequestKind2: [ // 如果请求有多个步骤(拆分到几个模块的), 可以用数组格式 {name, path}[]
{ name: 'step1', path: './src/mystep1' },
{ name: 'ajax', path: './src/request/myAjax' },
{ name: 'adaptor', path: './src/request/myAdaptor' },
...
]
自定义 kind 发布到 npm 包
如果团队有沉淀了一套稳定成熟的 kind, 希望在多个项目中以 npm 的形式复用, 而不是每次都要拷贝上述 api.config.js 文件, 可以使用如下方式发包.
npm 包的 index.js (或package.json指定的main) 所暴露的是如下格式
module.exports = {
myAjax: '[npm_package_name]/lib/myAdaptor',
myRequestKind2: [
{ name: 'step1', path: '[npm_package_name]/lib/mystep1' },
{ name: 'ajax', path: '[npm_package_name]/lib/myRequest' },
{ name: 'adaptor', path: '[npm_package_name]/lib/myAdaptor' },
...
]
}
在业务项目工程下, 安装该 npm 包, 然后在业务项目工程的 package.json 文件中加上这个配置项
"@api-loader-kinds": "[npm_package_name]"
// 或多个 npm 包组合
"@api-loader-kinds": [
"[npm_package1_name]",
"[npm_package2_name]",
...
]
注意, 如果上述 kind 有重名, 则后配置的 kind 会覆盖原有配置的 kind, 即覆盖顺序为 @ali/api-runtime < package.json("@api-loader-kinds") < api.config.js
Q&A
Q: A decorator can only decorate a method implementation, not an overload.怎么办 A: 安装最新的 Vscode Recore插件
Q: Unable to resolve signature of class decorator when called as an expression. A: 同上解决办法
Q: 自定义 kind 如何定义注解项 A: 参考 @ali/api-runtime/request/ajax
Q: 我没有用到的 kind 会占用打包体积吗 A: 不会, 是按需打包的
Q: 编译的数据结构为什么不用 json-schema A: 实际上已经是类 json-schema 了, 但由于 ts 有一些诸如 extends, &, 嵌套引用等用 json-schema 不好描述, 所以折中拓展了一下 json-schema
Q: 所有的 typescript 类型声明系统都支持吗 A: 并不. typescript 语法太多了, 有些其实反而带来阅读成本, 例如 omit 之类的. 我们设计 apits 的初衷是为了让人(协作)和机器(可视化)都能高效. ~~太复杂也难做静态语法分析和转义到 js 代码~~. 因此最复杂的能支持到如下类型声明
interface A {
a: Array<string>;
b: 'man' | 'woman' | 1 | true;
c: boolean | string;
d: number;
e: 1;
f: {
sub: string
}
}
interface B {
a: A;
b: string[];
}
interface C {
c: A & B & {x: string}
}
type D = A & B & {y: string};
interface E extends B, D {
e: number
}
即包含了 基础类型, extends, &, 嵌套, Array. 泛型目前只支持 Array. 不过 ts 官方建议写 xx[]. 所以等于是不支持泛型
changelog
0.7.9 支持 //@api-ignore 忽略段落
changelog
0.7.8 🐞fix windows 机器CRLF 0.7.7 🐞当返回类型漏写 Promise 时也能兼容 0.7.6 🐞复杂相互嵌套的场景下, 如 interface A {child: B}; interface B {child: A} 的支持 0.7.4 🐞type 声明自嵌套 fix 🐞npm 包的 type 报 typedeclare cant not use as variable 问题 0.7.1 ✨支持 windows 0.7.0 ✨支持 ts 类型组合/类型继承 ✨增加注解支持