如何在不编译为 JS 的情况下使用用 TypeScript 编写的自定义 tslint 规则和 vscode-tslint?
Posted
技术标签:
【中文标题】如何在不编译为 JS 的情况下使用用 TypeScript 编写的自定义 tslint 规则和 vscode-tslint?【英文标题】:How can I use a custom tslint rule written in TypeScript with vscode-tslint without compiling to JS? 【发布时间】:2019-10-24 18:11:09 【问题描述】:我在 TypeScript 中为 TSlint 编写了一个自定义规则,我可以在我的 Linux VM 上使用的脚本中使用 ts-node
运行它:
#!/bin/bash
set -e
ROOT_DIR=$(dirname $(dirname $0))
cd $ROOT_DIR
find "$ROOT_DIR/src" -name "*.ts" -o -name "*.tsx" | xargs $(yarn bin)/ts-node $(yarn bin)/tslint
这使得tslint
可以直接运行 TS 规则而无需先编译,并且确实有效。
问题是ms-vscode.vscode-typescript-tslint-plugin
没有选择该规则,即使它已在tsconfig.json
规则中明确启用。我在带有 Windows 主机的单独机器上运行 VSCode,通过 Linux VM 提供的 Samba 安装文件系统。文件中的其他规则被遵守并显示为已安装和内置的规则,如no-console
等。
我如何获得有关为什么不应用该规则的信息?我需要在插件中配置什么才能使其正常工作吗?
【问题讨论】:
github.com/microsoft/typescript-tslint-plugin/blob/master/src/… 我不太确定我可以从该文件中收集到什么信息。你是说 runner 需要实现规则文件的解析才能支持 TypeScript 规则? 我是说 vscode 插件的行为可能与 tslint CLI 工具不同。要找出原因,唯一的方法就是深入研究它的源代码。 ln:287 是它开始旋转 linter 的地方。该行周围的一些日志可以显示更多信息。 好的,谢谢你的指点,我会深入研究看看情况如何! 看起来插件只是让tslint
实例get configuration,这就是tslint
load rules
【参考方案1】:
这是我认为可能与问题有关的内容。
让我们将规则文件命名为noImportsRule.ts
。规则在 tslint.json
中使用其 kebab-cased 标识符引用,因此 "no-imports": true
将配置规则。
核心规则不能被自定义实现覆盖。
自定义规则也可以像核心规则一样接受选项(通过this.getOptions())
检索
从 TSLint v5.7.0 开始,您不再需要在使用自定义规则之前对其进行编译。您需要告诉 node.js 如何加载 .ts 文件,例如使用 ts-node:
重要约定:
规则标识符始终采用 kebab 大小写。 规则文件始终为驼峰式 (camelCasedRule.ts
)。
规则文件必须包含后缀Rule
。
导出的类必须始终命名为 Rule 并从 Lint.Rules.AbstractRule
扩展
所有details
【讨论】:
感谢您提供该信息,但该规则在 CLI 中运行良好,如上所述。我遇到的问题是 VS Code tslint 扩展不会在不编译为 JS 的情况下以.ts
形式加载规则。
我认为用你的 webpack babel 或 lint 配置编译成 js 很有趣。您应该说我不想在您的配置中公开为 js。你能分享你的配置吗?【参考方案2】:
不幸的是,这不受 VScode/vscode-typescript-tslint-plugin 的支持,并且似乎不在他们的议程中。
Here is a closed issue on their GitHub asking for this feature.
你当然可以先把你的规则编译成JS,但这不是你要求的。
【讨论】:
该存储库与 VSCode 的tslint
已弃用版本有关,因此我可能会提出请求,看看是否有办法在此版本中支持它。谢谢!
official stance 是这超出了新扩展的支持范围,所以我想这回答了这个问题。【参考方案3】:
我开发的 hack 是这样的:
-
假设您的自定义规则位于
./rules
下,该目录如下所示:
rules/
|- registerRule.js
|- oneRule.ts
|- twoRule.ts
oneRule.ts
和 twoRule.ts
是用 typescript 编写的实际规则,但 registerRule.js
是“间谍”。此间谍规则的目的只是让tslint
实例获取自身并将ts-node/register
注入节点运行时。
// registerRule.js
require('ts-node/register')
const Lint = require('tslint')
class Rule extends Lint.Rules.AbstractRule
apply(sourceFile)
return []
module.exports.Rule = Rule
-
设置
tslint.json
"rulesDirectory": "./rules",
"rules":
"register": true,
"one": true,
"two": true
我已经测试过了。这个 hack 将教会 vscode tslint 插件理解.ts
自定义规则。
【讨论】:
我想避免黑客攻击以支持ts-node
,因为它可能会对语言服务器产生不利影响并导致各种互操作问题。
@KlemenSlavič IMO,它在控制之下。它只会影响 require
对于任何带有 .ts
ext 的文件的行为,除此之外的其他内容不受影响以上是关于如何在不编译为 JS 的情况下使用用 TypeScript 编写的自定义 tslint 规则和 vscode-tslint?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不启动模拟器的情况下在 Eclipse 中将 Android 项目编译为 .apk 文件?
Deno 如何在不以“watch”模式运行 TypeScript 编译器的情况下快速启动