Featured image of post TypeScript + Vue, 防止 TSLint, Vetur, Prettier 打架的 VSCode 配置方式

TypeScript + Vue, 防止 TSLint, Vetur, Prettier 打架的 VSCode 配置方式

注:大忙人请直接跳到最后一节哦~

最近把 Yagt 的代码迁移到了 Standard 风格,就是这个:

JavaScript Style Guide

讲真,这个图标还是有点好看的。

不过之前项目一直使用开箱即用的 Prettier 插件(甚至连配置文件都没有,直接依赖 VSCode 自带的默认配置),而 Prettier 这个东西一直以「武断」著称,根本就不给你多少配置的空间。

没办法,只好先关了 Prettier,把 TSLint 装了起来。

顺带说一句,大概也就前两个月,TypeScript 团队宣布使用 ESLint 作为 TypeScript 和 VSCode 仓库的 Linter,ESLint 那边也表示欢迎,当天就放出了新的 typescript-eslint 项目。但是两个月后的现在,我在使用 ESLint 检查 TypeScript 代码时依然会遇到一些 BUG,因此这里就暂时依旧用着 TSLint 了。

yarn add -D tslint tslint-config-standard

再配置一下 tslint.json 和 tsconfig.json:

//tslint.json
{
  "extends": ["tslint:recommended", "tslint-config-standard"],
  "rules": {
    "max-line-length": [true, 80],
    //有些规则限制太死,先关一关
    "no-var-requires": false,
    "object-literal-sort-keys": false,
    "no-floating-promises": false,
    "forin": false
  }
}
//tsconfig.json
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "typescript-tslint-plugin",
        "configFile": "tslint.json",
        "alwaysShowRuleFailuresAsWarnings": true
      }
    ]
  }
}

装好之后,确实出现了不少的警告信息,并且自动修复也能正常工作。但是用着用着,突然发现了一个问题,就是 TSLint 在一行代码超过 80 字符时并不会自动帮你把代码分行(当然,如果 TSLint 抑或是 ESLint 真的能做到这点的话,就不会有 Prettier 这个东西存在了「误」),虽然确实是个小问题,不过对于我这种习惯了什么格式化任务都一个 Ctrl-S 全权交给 Prettier 处理的人来说,确实有点不爽。

这好办,把 Prettier 装回来不就好了……吗?

从这里起,事情就开始向着不可控的方向发展了……

TSLint + Prettier

启动 Prettier,开启editor.formatOnSave,然后……

这不对啊教练,怎么一按 Ctrl-S Prettier 就无视 TSLint 规则把分号又加回去了!

……哦抱歉,因为 Prettier 是一个「武断」的格式化工具。它才不管你 TSLint 啥规则呢。

这怎么办呢?

还好,虽说 Prettier 配置项少得可怜,但是起码还给你了集成 ESLint 和 TSLint 的方式,就是prettier.eslintIntegrationprettier.tslintIntegration

看来它们还是有一丝良知的嘛,感心感心(佩服佩服)。

在 VSCode 配置文件里把 Prettier 的 TSLint 集成打开:

"prettier.tslintIntegration": true
//启用下面这个VSCode默认的保存时格式化选项,Prettier会覆盖VSCode默认的规则
"editor.formatOnSave": true

现在的情况是:

  • VSCode::formatOnSave -> Prettier 的格式化器 -> TSLint 的规则

Ctrl-S 一下,emmm,看起来不错,除了需要多按几次保存之外没啥缺点了。

打开 Vue 文件,保存一下。

……

怎么没反应?

You gotta be kidding me,原来 TSLint 插件根本没办法访问到 Vue 文件里的<script>块。

TSLint + TSLint Vue + Prettier

行行行,访问不到也正常,谁让 Vue 单文件组件这么特殊呢。

商店里搜一波,找到了 TSLint Vue 插件,号称能帮助 lint .vue 文件。

装上装上。Ctrl-S,┏ (゜ ω ゜)=☞!

……

怎么还是没反应?

难道说不是 TSLint 的问题,而是 Prettier 访问不到.vue?

好吧,直接说结论。其实不是因为 Prettier 对.vue 失效,Prettier 自身确实无法获取.vue 里的<script>块,但是 vetur 插件帮我们解决了这个问题。但是 vetur 调用 Prettier 并没有关注它是否继承 TSLint 配置,因此实际上还是 Prettier 默认的规则!

TSLint + TSLint Vue + Vetur + Prettier

……有点糟糕。这样我们就只能启用tslint.autoFixOnSave,让 tslint 也参与到保存时的格式化过程中。但是,现在的情况就变成了:

  • TSLint::autoFixOnSave -> TSLint 的规则(无格式化)
  • Vetur::format.defaultFormatter.ts -> Prettier -> Prettier 默认规则(带格式化)

两个格式化过程之间规则的冲突导致了一个奇葩现象:

保存 - 分号被加上 - 保存 - 分号被去掉 - 保存 - 分号被加上 ……

因此最终,只能去掉第三条,也就是在配置文件里加上

"vetur.format.defaultFormatter.ts": "none"

来禁用掉 Vetur 对代码的格式化。

这样,我们还是失去了.vue 文件里代码的自动格式化。不过其实,由于 TSLint 本身也能处理一部分代码不规范的问题,因此只剩下自动换行这件事没有被实现。

那么问题来了,自动换行究竟是好还是坏呢?因为我目前已经遇到不少案例,Prettier 自动换行将我本就调好的格式给破坏掉了,而我又没办法修正,因为下次保存时又会被改回去。

但是,自动换行又可以节省人工调整格式的麻烦。毕竟,能自动化的东西为什么还要人手动来搞呢?

最终的配置文件

废话不多说。

//settings.json - VSCode配置文件
{
  ...
  "editor.formatOnSave": true,
  "prettier.tslintIntegration": true,
  "tslint.autoFixOnSave": true,
  "typescript.format.enable": false,
  "vetur.format.defaultFormatter.ts": "none"
  ...
}
//tslint.json - 自己想要啥就配啥
{
  "extends": ["tslint:recommended", "tslint-config-standard"],
  "rules": {
    "max-line-length": [true, 80],
    "no-var-requires": false,
    "object-literal-sort-keys": false,
    "no-floating-promises": false,
    "forin": false
  }
}
//tsconfig.json
{
  "compilerOptions": {
    ...
    "plugins": [
      {
        "name": "typescript-tslint-plugin",
        "configFile": "tslint.json",
        "alwaysShowRuleFailuresAsWarnings": true
      }
    ]
  }
}

以上。

Unless otherwise specified, all materials and content available on this website are licensed under CC BY-NC 4.0.
Built with Hugo
Theme Stack designed by Jimmy