注:大忙人请直接跳到最后一节哦~
最近把 Yagt 的代码迁移到了 Standard 风格,就是这个:
讲真,这个图标还是有点好看的。
不过之前项目一直使用开箱即用的 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.eslintIntegration
和prettier.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
}
]
}
}
以上。