Tslint: 支持 linting vue/html 文件

创建于 2017-01-22  ·  35评论  ·  资料来源: palantir/tslint

功能要求

  • __TSLint 版本__: 4.3.1
  • __TypeScript 版本__: 2.1.5
  • __通过__运行TSLint:Node.js API

正在整理 TypeScript 代码

<template>
  <q-layout>
    <div slot="header" class="toolbar">
      <q-toolbar-title :padding="0">
        Quasar Framework v{{quasarVersion}}
      </q-toolbar-title>
    </div>

    <!--
      Replace following "div" with
      "<router-view class="layout-view">" component
      if using subRoutes
    -->
    <div class="layout-view">
      <div class="logo-container non-selectable no-pointer-events">
        <div class="logo" :style="position">
          <img src="~assets/quasar-logo.png">
          <p class="caption text-center">
            <span class="desktop-only">Move your mouse!!!.</span>
            <span class="touch-only">Touch screen and move.</span>
          </p>
        </div>
      </div>
    </div>
  </q-layout>
</template>

<script lang="ts">
  import * as Quasar from 'quasar';
  import { Utils } from 'quasar';
  import * as Vue from 'vue';
  import Component from 'vue-class-component';

  const moveForce = 30;
  const rotateForce = 40;

  @Component({
  })
  export default class Index extends Vue {
    rotateX: number;
    rotateY: number;
    moveY: number;
    moveX: number;
    quasarVersion: string;
   ...  
 }
</script>

<style lang="stylus">
....
</style>

使用tslint.json配置:

{
  "rules": {
    "class-name": true,
    "curly": true,
    "eofline": false,
    "expr" : true,
    "forin": true,
    "indent": [true, "spaces"],
    "label-position": true,
    "label-undefined": true,
    "max-line-length": [true, 140],
    "no-arg": true,
    "no-bitwise": true,
    "no-console": [true,
      "debug",
      "info",
      "time",
      "timeEnd",
      "trace"
    ],
    "no-construct": true,
    "no-debugger": true,
    "no-duplicate-key": true,
    "no-duplicate-variable": true,
    "no-empty": true,
    "no-eval": true,
    "no-string-literal": false,
    "no-switch-case-fall-through": true,
    "no-trailing-comma": true,
    "no-trailing-whitespace": true,
    "no-unused-expression": false,
    "no-unused-variable": true,
    "no-unreachable": true,
    "no-use-before-declare": true,
    "one-line": [true,
      "check-open-brace",
      "check-catch",
      "check-else",
      "check-whitespace"
    ],
    "quotemark": [true, "single"],
    "radix": false,
    "semicolon": [false],
    "triple-equals": [true, "allow-null-check"],
    "variable-name": false,
    "whitespace": [true,
      "check-branch",
      "check-decl",
      "check-operator",
      "check-separator",
      "check-type"
    ]
  }
}

实际行为

尝试 lint 整个文件并失败。

预期行为

只检查脚本标签内的代码,类似于 eslint。

Aged Away Feature Request

最有用的评论

这里还有一些消息? 🤙

所有35条评论

@nrip-monotype,您可以通过配置vue-loader将 TSLint 与 Vue 单文件组件一起使用。 例如,在2的WebPack我使用它像这样(看看在loaders的选项vue-loader ):

module: {
        rules: [
            {
                enforce: 'pre',
                test: /\.ts$/,
                loader: 'tslint-loader',
                exclude: /(node_modules)/,
                options: {
                    configFile: 'tslint.json'
                }
            },
            {
                test: /\.ts$/,
                exclude: /node_modules|vue\/src/,
                loader: 'ts-loader',
                options: {
                    appendTsSuffixTo: [/\.vue$/],
                    transpileOnly: true,
                    isolatedModules: true
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        ts: 'ts-loader!tslint-loader'
                    }
                }
            },
        }
    }
}

@romandragan ,您的建议有效,但no-consecutive-blank-lines似乎有问题。 似乎标记元素被空行替换,例如:

<template>
   <span class='hello'>hello world</span>
</tempalte>
<script lang="ts">
    return {};
</script>
<style>
    .hello { background-color: pink }
</style>

被 tslint 视为:

    return {};




如果我设置"no-consecutive-blank-lines": [true, 3]它失败,但"no-consecutive-blank-lines": [true, 4]成功...知道如何解决这个问题吗? (缺少另一个去除前导和尾随空格的插件......)

@lucastheisen ,对我来说同样的问题😞 试图找到解决方案......

@romandragan的设置对我typeCheck标志在 vue-loader 中不起作用。 您仍然可以在 vue-loader 之外正常使用它。

>

module: {
        rules: [
            {
                enforce: 'pre',
                test: /\.ts$/,
                loader: 'tslint-loader',
                exclude: /(node_modules)/,
                options: {
                    configFile: 'tslint.json'
                }
            },
            {
                test: /\.ts$/,
                exclude: /node_modules|vue\/src/,
                loader: 'ts-loader',
                options: {
                    appendTsSuffixTo: [/\.vue$/],
                    transpileOnly: true,
                    isolatedModules: true,
                    typeCheck: true // This is ok.
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        ts: 'ts-loader!tslint-loader' // Can't append `?typeCheck` here.
                    }
                }
            },
        }
    }
}

尝试在 vue-loader 中使用类型检查规则会产生如下错误:

ERROR in ./app.ts
(10,29): error TS2307: Cannot find module './components/sidebar.vue'.

ERROR in ./~/ts-loader!./~/tslint-loader?formatter=verbose&typeCheck!./~/vue-loader/lib/selector.js?type=script&index=0!./components/sidebar.vue
Module build failed: Error:
Invalid source file: /absolute/path/to/sidebar.vue. Ensure that the files supplied to lint have a .ts, .tsx, .js or .jsx extension.

我也得到了与@lucastheisen和 @romandragan 相同的no-consecutive-blank-lines误报。

使用此配置时,我收到此ERROR in Entry module not found: Error: Can't resolve 'ts-loader!tslint-loader'

            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        ts: 'ts-loader!tslint-loader'
                    }
                }
            },

@ARomancev ,您使用的是什么版本的 webpack? 你安装了ts-loadertslint-loader npm 模块吗?

@romandragan ,这是我使用的 npm 配置:
``
"tslint": "^5.1.0",
"ts-loader": "^2.0.3",
"webpack": "^2.4.1",

And this is the webpack config:
  {
    test: /\.tsx?$/,
    enforce: 'pre',
    loader: 'tslint-loader'
  },
  {
    test: /\.tsx?$/,
    loader: 'ts-loader',
    exclude: /node_modules/,
    options: {
      appendTsSuffixTo: [/\.vue$/]
    }
  },

``
ts-loader 和 tslint-loader 都已安装并且工作正常,因为我从 *.ts 文件中获得了正确的 lint。

作为一种解决方法,我们可以将 TypeScript 逻辑从 .vue 文件中分离出来,并从 vue 加载器中删除tslint-loader 。 然后, no-consecutive-blank-lines消失了。

@romandragan这有效,但在<script>标签内 lint 代码也很好:这是编辑器支持所必需的,并且单独运行tslint命令要容易得多,而不是通过整个 webpack流动。

@adidahiya这个功能有什么计划吗?
或任何计划在 tslint 中支持插件系统,如 eslint 插件?

如果您使用的是 Webpack,我有.vue文件在类型检查器级别工作和 linting,在no-consecutive-blank-lines问题。 您可以在此处查看 PR(以及来自测试分支的npm install并立即使用它,请参阅 PR 线程的顶部): https :

另外,如果您使用的是 VSCode 编辑器,请查看TSLint Vue 扩展

我创建了一个在 tslint 中实现插件功能的拉取请求,并编写了第一个能够解析“vue”单文件组件的插件。

https://github.com/palantir/tslint/pull/3596
https://github.com/Toilal/tslint-plugin-vue

这是一项正在进行的工作,但请随意尝试。 您可以使用npm install git+https://https://github.com/Toilal/tslint-plugin-vue添加插件,并通过将plugins: 'vue'tslint.json启用它。 目前它不适用于-p/--project选项,您必须使用-c/--config选项。

大家好,目前另一种替代解决方案是移动文件开头的脚本标记,并在最后一行添加/* tslint:disable:no-consecutive-blank-lines */以不考虑此规则。
检查下面的图像
image

Vue-loader实际上可以从 vue 文件中提取 JavaScript 或 TypeScript,所以解析 vue 文件对于 webpack 来说不是问题。 但是,如果启用了 typeCheck,TSLint 仍然会抛出“无效的源文件”,因为文件名以“.vue”结尾...

此外,我们可以通过在 vue 文件的开头或结尾允许连续的空行来让 TSLint 停止抱怨连续的空行,因为 vue-loader 不会删除与 TypeScript 无关的行,而是清除它们以保持正确的行号。

我目前正在研究一种无需 webpack 即可解决这些问题的 linter: https :
这是目前的概念证明,可能会或可能不会集成到 TSLint 中。 这是从头开始完全重写,与 TSLint 几乎不兼容。

它具有使用处理器(类似于 ESLint 处理器)转换文件的能力。 vue 处理器从 SFC 中提取 TypeScript 代码,linter 仅对代码进行 lint,然后处理器将错误映射到原始文件中的正确位置。 这甚至适用于类型检查。
您可以在此处查看 linting vue 文件的示例输出:
https://github.com/ajafff​​/wotan/blob/master/baselines/integration/processors/vue/default/hello.vue.lint#L29

它还允许自动固定。 与上述相同的文件自动修复: https :

一旦我修复了https://github.com/ajafff​​/wotan/issues/32,我将发布一个版本,以便您可以在现实世界的代码上进行尝试。
请注意,vue 处理器不是主项目的一部分,但我会确保为处理器发布一个单独的包。

有谁知道我将如何设置tsconfig.json以便命令行 tslint 将 lint Vue 文件的 TS 部分? 它在 VS Code 中运行良好,但我希望命令行也能运行。

我花了比我想象的更长的时间,但这里是: https :

您甚至可以使用 linter 运行时 ( @fimbul/wotan ) 来执行 TSLint 规则。 你只需要@fimbul/heimdall ,见https://github.com/fimbullinter/wotan/tree/master/packages/heimdall#readme

要 lint Vue 文件,请使用@fimbul/ve (没有错别字,'ve' 中没有 'u'): https :

tslint 何时支持 linting vue/html 文件有时间表吗? @劳拉

实现这一点取决于社区,但 VueJS 作者似乎更喜欢 ESLint TypeScript 插件,而不是在 vue-cli 的最新版本(目前处于 alpha 阶段)。

此功能似乎已在[email protected] 。 跑:

$ npm install -g @vue/cli
$ vue create project-name

并且可以选择使用 TSLint 作为 linter。

我回来给这个线程上的每个人带来更大的消息:

最新版本的wotan可以根据你的tslint.json执行TSLint规则,并增加了对处理器的支持。 这意味着您不必更改配置,现在就可以开始整理 Vue 文件:

  1. 安装
    sh yarn add -D @fimbul/wotan @fimbul/ve @fimbul/valtyr # or npm install --save-dev @fimbul/wotan @fimbul/ve @fimbul/valtyr
  2. 配置
    在你的项目根目录下新建一个文件.fimbullinter.yaml ,添加如下内容:
    yaml modules: "@fimbul/valtyr" valtyr: overrides: - files: "*.vue" processor: "@fimbul/ve"

  3. 请参阅下面的示例并适应您自己的使用。 阅读文档以获取有关可用 CLI 参数的更多信息。
    sh wotan # finds tsconfig.json and lints the whole project with type information according to your tslint.json wotan 'src/**/*.vue' -f verbose # lint all Vue files, use TSLint's verbose formatter wotan -p tsconfig.json -c tslint.json --fix # lint the whole project with tslint.json and fix failures
  4. 进一步阅读
    Wotan - CLI 和配置: https :
    Valtýr - TSLint 规则和格式化程序插件 - “比 TSLint 更好的 TSLint 运行时”: https :
    Vé - Vue 单文件组件的处理器: https :
    Fimbullinter - 为什么你现在应该开始使用这个项目: https :
  5. 喜欢,分享和订阅 :star:

@罗曼德拉根

您可以通过配置 vue-loader 将 TSLint 与 Vue 单文件组件一起使用。

感谢您的解决方案。 但这只是 Webpack 特定的解决方案。 如果有一个不依赖于构建工具的通用解决方案,以便我们可以 tslint 使用Fusebox (或任何其他构建工具)编译的 Vue 文件,那就太好了。

webpack 的另一种解决方案。

我创建了一个简单的加载器,它从 vue-loader 提供的“文件”中删除所有空格,然后为 linter 添加空格。

webpack.config.js:

test:/\.vue$/, loader: 'vue-loader', options: { loaders: { 'ts': [ 'vue-ts-loader', 'tslint-loader', path.resolve('./path/to/remove-whitespace-ts-loader.js') ],....

然后删除-whitespace-ts-loader:
/* MIT License http://www.opensource.org/licenses/mit-license.php Author Szymon Sasin */ module.exports = function(source) { let result = source.replace(/^\s+|\s+$/g, '') result += '\r\n' return result; }
_任何有关如何改进代码格式的帮助都欢迎_

它工作正常并且允许不修改源,谢谢

就这样我在同一页面上,除非作为 PR 完成,否则这不会被修复吗?

除了no-consecutive-blank-lines在此设置中不起作用(应该可以使用自定义加载器解决),我只是注意到,即使使用最近的 webpack 和 vue-loader 版本,我也无法获得typeCheck: true适用于*.vue文件,因为tslint对扩展名不满意(即使使用appendTsSuffixTo )。 这个演示项目给出了一个简单的例子。

标记

这里还有一些消息? 🤙

如果有人想使用 cli lint 你的 .vue 文件,你可以试试vue-tslint 。 它并不完美,但它有效......

请注意, @romandragan的解决方案现在不是最佳实践(不确定以前是否如此)。 相反,将tslint-loaderuse中的\.ts$规则中,就像通常的打字稿文件一样; 现在vue-loader处理一般的模板文件,将不同的部分委派给您的 Webpack 配置,用于相应的扩展。 vue-loader的插件组件将提取\.ts$的规则,并通过这些规则流式传输<script lang="ts">块。

对于那些使用 Vue CLI 的人,添加一个

config.module.rule('ts')
  .use('tslint-loader')
  .loader('tslint-loader');

声明你的chainWebpack选择在您的vue.config.js 。 例如,

vue.config.js

module.exports = {
  chainWebpack: (config) => {
    config.devtool('source-map');
    config.module.rule('ts')
      .use('tslint-loader')
      .loader('tslint-loader');
  },
  pluginOptions: {
    apollo: {
      enableMocks: true,
      enableEngine: true
    }
  }
}

这对我有用

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')

module.exports = (baseConfig, env, defaultConfig) => {
  defaultConfig.resolve.extensions.push('.ts', '.tsx', '.vue', '.css', '.less', '.scss', '.sass', '.html')

  defaultConfig.module.rules.push( {
    test: /\.ts$/,
    exclude: /(node_modules)/,
    use: [
      {
        loader: 'ts-loader',
        options: {
          appendTsSuffixTo: [/\.vue$/]
          // transpileOnly: true,
        }
      },
      {
        loader: 'tslint-loader',
        options: {
          configFile: 'tslint.json',
          emitErrors: true,
        }
      }
    ]
  })

  defaultConfig.module.rules.push({ test: /\.less$/, loaders: [ 'style-loader', 'css-loader', 'less-loader' ] })
  defaultConfig.module.rules.push({ test: /\.scss$/, loaders: [ 'style-loader', 'css-loader', 'sass-loader' ] })
  defaultConfig.module.rules.push({ test: /\.styl$/, loader: 'style-loader!css-loader!stylus-loader' })

  defaultConfig.plugins.push(new ForkTsCheckerWebpackPlugin())

  return defaultConfig
}

根据 #4379,特定于 Vue 的解决方法将无法登陆 TSLint 核心:

鉴于此处缺乏讨论或具体建议,以及即将弃用 TSLint 以支持 ESLint (#4534),我将继续关闭此问题和相关的 Vue 特定报告,以用于内务管理。

如果这对您来说仍然是typescript-eslint的问题,我建议您在那里提交问题。 祝你好运!

./node_modules/.bin/wotan 'src/ */ .vue' -f 详细

崩溃:

Error: ENOENT: no such file or directory, open '/home/andrew/PycharmProjects/djangochat/fe/src/components/App.vue.ts'
    at Object.openSync (fs.js:451:3)
    at detectEncoding (/home/andrew/PycharmProjects/djangochat/fe/node_modules/tslint/lib/rules/encodingRule.js:67:17)
    at walk (/home/andrew/PycharmProjects/djangochat/fe/node_modules/tslint/lib/rules/encodingRule.js:49:20)
    at Rule.AbstractRule.applyWithFunction (/home/andrew/PycharmProjects/djangochat/fe/node_modules/tslint/lib/language/rule/abstractRule.js:39:9)
    at Rule.apply (/home/andrew/PycharmProjects/djangochat/fe/node_modules/tslint/lib/rules/encodingRule.js:33:21)
    at R.apply (/home/andrew/PycharmProjects/djangochat/fe/node_modules/@fimbul/bifrost/src/index.js:30:40)
    at Linter.applyRules (/home/andrew/PycharmProjects/djangochat/fe/node_modules/@fimbul/wotan/src/linter.js:209:31)
    at Linter.getFindings (/home/andrew/PycharmProjects/djangochat/fe/node_modules/@fimbul/wotan/src/linter.js:125:25)
    at Runner.lintFiles (/home/andrew/PycharmProjects/djangochat/fe/node_modules/@fimbul/wotan/src/runner.js:159:43)
    at lintFiles.next (<anonymous>) {
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path: '/home/andrew/PycharmProjects/djangochat/fe/src/components/App.vue.ts'
}

@akoidan请提出类似 wotan 项目的问题,而不是 tslint

此页面是否有帮助?
0 / 5 - 0 等级