如何在不编译为 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,这就是tslintload 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.tstwoRule.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 编译器的情况下快速启动

如何在不影响进程的空格的情况下替换js中的文本

如何在不使用 jquery 插件的情况下快速跳转到下一部分?

如何在不使用 npm 的情况下安装 node.js 模块?

如何在不使用 cytoscape.js 重绘图形的情况下删除特定边?