相关文章推荐
豪爽的手套  ·  javascript - ...·  3 年前    · 
打酱油的西装  ·  Vue.js3 + Vite + ...·  3 年前    · 
飘逸的萝卜  ·  Android:java.lang.Asse ...·  3 年前    · 
Skip to content
@wakeadmin/components
On this page

支持 Typescript 和 JSX

在 Vue 中开启 Typescript 和 JSX 支持并不是一件容易的事情 。 因此我们单独出一份文档来说明一下。




依赖

如果你想要使用 TSX / JSX 开发,并且获取到更好的 Typescript 类型检查,需要安装以下依赖:



  • babel-preset-wakeadmin 使用 react jsx 的标准语法来转换 JSX。
  • @wakeadmin/h 更好地支持 react-jsx 的标准 JSX 语法,没有语法糖,更接近 React 的开发体验。兼容 Vue 2/3。详见 下文
  • @wakeadmin/demi fork from vue-demi , 修复了一些问题。可以完全取代 vue-demi
  • vue-tsc Volar 底层依赖的 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-tsc :

如果使用了惟客云 自动化检查工具 , 可以这样配置:





更好地支持 JSX/TSX


大部分场景,我们推荐你使用 Vue 的 SFC + setup + TypeScript 来编写组件。


然而,在你们使用 @wakeadmin/components 时,为了灵活定义组件库,你会经常用到 JSX。


假设你的项目使用是 Vue-cli, 第一步先修改 babel.config.js



接着修改 tsconfig.json 配置:




这里,我们使用 @wakeadmin/h 来编写 JSX。好处是:


  1. 不管你用的是 Vue 2, 还是 Vue 3, 使用 @wakeadmin/h 可以提供一致的编写方式 , 更接近我们在 React 上的使用习惯。

    • Vue 2 / 3 JSX 书写上 相差非常大
    • Vue 官方的 JSX 库携带了很多语法糖。这依赖于 Babel 的转换,这意味着你无法直接使用 esbuild、Typescript 这类工具进行编译。
  2. 除此之外, @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 同理: