支持 Typescript 和 JSX
在 Vue 中开启 Typescript 和 JSX 支持并不是一件容易的事情 。 因此我们单独出一份文档来说明一下。
依赖
如果你想要使用
TSX
/
JSX
开发,并且获取到更好的
Typescript
类型检查,需要安装以下依赖:
-
babel-preset-wakeadmin使用 react jsx 的标准语法来转换 JSX。 -
@wakeadmin/h更好地支持 react-jsx 的标准 JSX 语法,没有语法糖,更接近 React 的开发体验。兼容 Vue 2/3。详见 下文 -
@wakeadmin/demifork fromvue-demi, 修复了一些问题。可以完全取代vue-demi -
vue-tscVolar 底层依赖的 Typescript 编译器。这里主要用于类型检查
建议将 @wakeadmin/* 相关库都升级到最新版本
构建
首先根据你使用的构建工具,配置相关的 Typescript 构建支持:
-
Vite: 内置支持转换 , 但是类型检查需要借助vue-tsc -
Vue CLI: 卸载掉@vue/cli-plugin-typescript, 并安装@wakeadmin/vue-cli-plugin-typescript。这个插件底层基于esbuild进行编译, 不会进行类型检查 , 因此还是需要借助vue-tsx, 详见 下文 。
💥 不推荐使用
@vue/cli-plugin-typescript
插件:
为什么不使用它?
Vue 官方也不推荐使用它
。一个比较重要的问题是,它的执行结果未必和 IDE 一致,异常也很难排查。性能也较差、无法同 vue-tsc 一样真正检查
*.vue
文件。
配置
接着配置 tsconfig.json:
接着,配置一个
src/env.d.ts
(旧的项目可能已存在, 比如 vue-cli,
shims-tsx.d.ts
、
shims-vue.d.ts
, 将这些文件删掉) 文件,让 TypeScript
标准
的类型检查器可以识别
*.vue
文件:
.vue
文件, 像
.css
这些静态资源文件一样, 标准的 Typescript 是无法识别里面的类型的
, 当然装了 Volar 插件之后, Valor 可以做到。但是仅在 IDE 层面,如果你想要在构建时/CI 时进行类型检查,可以用
vue-tsc
IDE 类型提示
IDE
上推荐使用
Valor
插件,并
禁用掉
Vetur
插件
。在 VSCode 中, 你可以安装一下两个插件:
- Vue Language Features : Vue, Vitepress, petite-vue language support extension for VSCode
- TypeScript Vue Plugin VSCode extension to support Vue in TS server
开启类型检查
最后,如果想要对类型进行检查,推荐使用
vue-tsc
:
如果使用了惟客云 自动化检查工具 , 可以这样配置:
更好地支持 JSX/TSX
大部分场景,我们推荐你使用 Vue 的 SFC + setup + TypeScript 来编写组件。
然而,在你们使用
@wakeadmin/components
时,为了灵活定义组件库,你会经常用到 JSX。
假设你的项目使用是 Vue-cli, 第一步先修改
babel.config.js
接着修改
tsconfig.json
配置:
这里,我们使用
@wakeadmin/h
来编写 JSX。好处是:
-
不管你用的是 Vue 2, 还是 Vue 3, 使用
@wakeadmin/h可以提供一致的编写方式 , 更接近我们在 React 上的使用习惯。- Vue 2 / 3 JSX 书写上 相差非常大
- Vue 官方的 JSX 库携带了很多语法糖。这依赖于 Babel 的转换,这意味着你无法直接使用 esbuild、Typescript 这类工具进行编译。
-
除此之外,
@wakeadmin/h也优化了 Vue JSX 在 Typescript 支持上的一些问题。
使用示例:
ESLint 适配
你可以使用
wkstd init
来初始化 eslint 的配置, 典型的 ESlint 配置如下:
然而可能不会像你想象的那么顺利。
❌ 异常 1: Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser. The file does not match your project config: packages/eslint-config-wkvue/ tests /vue2/ts/.eslintrc.js. The file must be included in at least one of the projects provided
原因分析
: 我们在上面的 eslint 配置中指定了
@typescript-eslint/parser
作为所有文件 parser。然而
@typescript-eslint/parser
, 如果指定的文件不再 tsconfig.json 的覆盖范围之内就会出现该问题。
解决办法:
-
① (不推荐)在 tsconfig.json include 进来, 比如:
对于旧的项目,这些文件很多。这种解法比较蠢,而且会影响 Typescript 的检查效率,甚至会污染检查的结果。如果真的非得用这种方式,可以另起一个
tsconfig.eslint.json的配置文件,并将parserOptions.project指向这个文件。
-
② 为不同的文件支持不同的 parser
tsconfig.json应该专注于应该检查的文件:
接着配置 eslintrc 对不同的文件使用不同的 parser 进行处理:
-
③ (推荐) 一个更简单的办法是开启 typescript-eslint 的
createDefaultProgram选项:简单的代价是性能会稍差一些。
❌ 异常 2: 如果你要在 Vue SPA 中使用
<script lang="tsx"></script>
, Eslint 可能会报错,你需要以下配置:
老项目中启用 TypeScript
老项目(假设是 Vue 2)中也可以按照上文的配置开启 Typescript。有以下几个要点
-
开启
tsconfig.json的 allowJS, 而不是 checkJS。这表示允许和 Javascript 混用,但不检查 Javascript。如果开启 checkJS 可能有成吨的异常抛出来。 -
如何扩展 Vue 的类型?比如全局方法、全局对象、全局组件等等。 Vue 2/3 定义方式有点区别, 这里展示 Vue 2 的使用方式 ,你也可以参考相关的第三方库。以 vue-router 为例
扩展全局组件实例成员:
扩展 optional API
扩展全局组件:
element-ui
同理: