Tslint: рд╕рдорд░реНрдерди рд▓рд╛рдЗрдирд┐рдВрдЧ vue/html рдлрд╝рд╛рдЗрд▓

рдХреЛ рдирд┐рд░реНрдорд┐рдд 22 рдЬрдире░ 2017  ┬╖  35рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: palantir/tslint

рдорд╣рддреНрд╡рдкреВрд░реНрдг рд▓реЗрдЦ рдорд╛рдВрдЧрдирд╛

  • __TSLint рд╕рдВрд╕реНрдХрд░рдг__: 4.3.1
  • __рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдВрд╕реНрдХрд░рдг__: 2.1.5
  • __TSLint рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓ рд░рд╣рд╛ рд╣реИ__: Node.js API

рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рдкрдВрдХреНрддрд┐рдмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ

<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"
    ]
  }
}

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡реНрдпрд╡рд╣рд╛рд░

рдкреВрд░реА рдлрд╛рдЗрд▓ рдХреЛ рд▓рд┐рдВрдЯ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИред

рдЕрдкреЗрдХреНрд╖рд┐рддреН рд╡реНрдпрд╡рд╣рд╛рд░

рдПрд╕реНрд▓рд┐рдВрдЯ рдХреЗ рд╕рдорд╛рди, рдХреЗрд╡рд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдХреЗ рдЕрдВрджрд░ рдХреЛрдб рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВред

Aged Away Feature Request

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдпрд╣рд╛рдВ рдХреБрдЫ рдФрд░ рдЦрдмрд░реЗрдВ? рдореИрдВ

рд╕рднреА 35 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

@ nrip-monotype, рдЖрдк vue-loader рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдХреЗ Vue рдПрдХрд▓ рдлрд╝рд╛рдЗрд▓ рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде TSLint рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╡реЗрдмрдкреИрдХ 2 рдореЗрдВ рдореИрдВ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ ( 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 tslint-loader рдХреЗ рд▓рд┐рдП рдзреНрд╡рдЬ 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 , рдЖрдк ts-loader рдФрд░ tslint-loader npm рдореЙрдбреНрдпреВрд▓ рд╕реНрдерд╛рдкрд┐рдд рд╣реИрдВ?

@romandragan , рдпрд╣рд╛рдБ
```
"tslint": "^5.1.0",
"рдЯреАрдПрд╕-рд▓реЛрдбрд░": "^2.0.3",
"рд╡реЗрдмрдкреИрдХ": "^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 рдлрд╛рдЗрд▓реЛрдВ рд╕реЗ рд╕рд╣реА рд▓рд┐рдВрдЯ рдорд┐рд▓рддрд╛ рд╣реИред

рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЗ рд░реВрдк рдореЗрдВ рд╣рдо рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓реЙрдЬрд┐рдХ рдХреЛ .vue рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ tslint-loader рдХреЛ vue рд▓реЛрдбрд░ рд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдлрд┐рд░, no-consecutive-blank-lines рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

@romandragan рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди <script> рдЯреИрдЧ рдХреЗ рдЕрдВрджрд░ рдХреЛрдб рдХреЛ рд▓рд┐рдВрдЯ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛: рдпрд╣ рд╕рдВрдкрд╛рджрдХ рд╕рдорд░реНрдерди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдФрд░ tslint рдХрдорд╛рдВрдб рдХреЛ рдЕрд▓рдЧ рд╕реЗ рдЪрд▓рд╛рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ, рдмрд▓реНрдХрд┐ рдкреВрд░реЗ рд╡реЗрдмрдкреИрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрд╣реЗред

@adidahiya рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдпреЛрдЬрдирд╛?
рдпрд╛ рдПрд╕реНрд▓рд┐рдВрдЯ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреА рддрд░рд╣ tslint рдореЗрдВ рд╕рдорд░реНрдерди рдкреНрд▓рдЧрдЗрди рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдпреЛрдЬрдирд╛?

рдпрджрд┐ рдЖрдк рд╡реЗрдмрдкреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рдлреЛрд░реНрдХ-рдЯреАрдПрд╕-рдЪреЗрдХрд░-рд╡реЗрдмрдкреИрдХ-рдкреНрд▓рдЧрдЗрди рдореЗрдВ .vue рдлрд╛рдЗрд▓реЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣реА рд╣реИрдВ рдФрд░ рдЯрд╛рдЗрдкрдЪреЗрдХрд░ рд╕реНрддрд░ рдкрд░ рдХреЛрдИ no-consecutive-blank-lines рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред рдЖрдк рдпрд╣рд╛рдВ рдкреАрдЖрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ (рдФрд░ рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╢рд╛рдЦрд╛ рд╕реЗ npm install рдФрд░ рдЕрднреА рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдкреАрдЖрд░ рдереНрд░реЗрдб рдХреЗ рд╢реАрд░реНрд╖ рджреЗрдЦреЗрдВ): https://github.com/Realytics/fork-ts-checker-webpack-plugin /рдкреБрд▓/77

рд╕рд╛рде рд╣реА, рдпрджрд┐ рдЖрдк 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 рдлрд╝рд╛рдЗрд▓реЛрдВ рд╕реЗ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдпрд╛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рдХрд╛рд▓ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП vue рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдирд╛ рд╡реЗрдмрдкреИрдХ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, TSLint рдЕрднреА рднреА "рдЕрдорд╛рдиреНрдп рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓" рдлреЗрдВрдХрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо ".vue" рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ рдпрджрд┐ рдЯрд╛рдЗрдкрдЪреЗрдХ рд╕рдХреНрд╖рдо рд╣реИ ...

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЯреАрдПрд╕рд▓рд┐рдВрдЯ рдХреЛ рд╡реАрдпреВ рдлрд╛рдЗрд▓реЛрдВ рдХреА рд╢реБрд░реБрдЖрдд рдпрд╛ рдЕрдВрдд рдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ рд░рд┐рдХреНрдд рд▓рд╛рдЗрдиреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдХрд░ рд▓рдЧрд╛рддрд╛рд░ рдЦрд╛рд▓реА рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╢рд┐рдХрд╛рдпрдд рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реАрдпреВ-рд▓реЛрдбрд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рдЕрдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдирд╣реАрдВ рд╣рдЯрд╛рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рд╕рд╣реА рд▓рд╛рдЗрди рдирдВрдмрд░ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рдмрдЬрд╛рдп рдЙрдиреНрд╣реЗрдВ рд╕рд╛рдл рдХрд░рддрд╛ рд╣реИред

рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рд▓рд┐рдВрдЯрд░ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬреЛ рд╡реЗрдмрдкреИрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛ рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИ: https://github.com/ajafff/wotan
рдпрд╣ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдкреНрд░рдорд╛рдг рд╣реИ рдФрд░ TSLint рдореЗрдВ рдПрдХреАрдХреГрдд рд╣реЛ рднреА рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдирд╣реАрдВ рднреАред рдпрд╣ рдЦрд░реЛрдВрдЪ рд╕реЗ рдПрдХ рдкреВрд░реНрдг рдкреБрдирд░реНрд▓реЗрдЦрди рд╣реИ рдФрд░ TSLint рдХреЗ рд╕рд╛рде рдХрд╛рдлреА рдЕрд╕рдВрдЧрдд рд╣реИред

рдЗрд╕рдореЗрдВ рдПрдХ рдкреНрд░реЛрд╕реЗрд╕рд░ (ESLint рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рд╕рдорд╛рди) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдПрдХ рд╡реАрдпреВ рдкреНрд░реЛрд╕реЗрд╕рд░ рдПрд╕рдПрдлрд╕реА рд╕реЗ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИ, рд▓рд┐рдВрдЯрд░ рдХреЗрд╡рд▓ рдХреЛрдб рдХреЛ рд▓рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ рдкреНрд░реЛрд╕реЗрд╕рд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдореВрд▓ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рд╣реА рд╕реНрдерд╛рди рдкрд░ рдореИрдк рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдЖрдк рдпрд╣рд╛рдБ рдПрдХ Vue рдлрд╝рд╛рдЗрд▓ рдХреЛ рд▓рд╛рдЗрди рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдирдореВрдирд╛ рдЖрдЙрдЯрдкреБрдЯ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ:
https://github.com/ajafff/wotan/blob/master/baselines/integration/processors/vue/default/hello.vue.lint#L29

рдпрд╣ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдлрд┐рдХреНрд╕рд┐рдВрдЧ рдХреА рднреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдКрдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╣реА рдлрд╝рд╛рдЗрд▓ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рддрдп: https://github.com/ajafff/wotan/blob/master/baselines/integration/processors/vue/default/hello.vue#L28

рдПрдХ рдмрд╛рд░ рдЬрдм рдореИрдВрдиреЗ https://github.com/ajafff/wotan/issues/32 рддрдп рдХрд░ рд▓рд┐рдпрд╛ рддреЛ рдореИрдВ рдПрдХ рд░рд┐рд▓реАрдЬ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░реВрдВрдЧрд╛ рддрд╛рдХрд┐ рдЖрдк рдЗрд╕реЗ рдЕрдкрдиреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд┐рд╢реНрд╡ рдХреЛрдб рдкрд░ рдЖрдЬрдорд╛ рд╕рдХреЗрдВред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ Vue рдкреНрд░реЛрд╕реЗрд╕рд░ рдореБрдЦреНрдп рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдореИрдВ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдкреИрдХреЗрдЬ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░реВрдВред

рдХреНрдпрд╛ рдХрд┐рд╕реА рдХреЛ рдкрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ tsconfig.json рдХреИрд╕реЗ рд╕реЗрдЯ рдХрд░реВрдВрдЧрд╛ рддрд╛рдХрд┐ рдХрдорд╛рдВрдб-рд▓рд╛рдЗрди tslint рдореЗрд░реА Vue рдлрд╛рдЗрд▓реЛрдВ рдХреЗ TS рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рд▓рд┐рдВрдЯ рдХрд░ рд╕рдХреЗ? рдпрд╣ рд╡реАрдПрд╕ рдХреЛрдб рдореЗрдВ рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рднреА рдХрд╛рдо рдХрд░реЗред

рдореИрдВрдиреЗ рдЬрд┐рддрдирд╛ рд╕реЛрдЪрд╛ рдерд╛ рдЙрд╕рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рд╕рдордп рд▓рд┐рдпрд╛, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдБ рдпрд╣ рд╣реИ: https://www.npmjs.com/package/@fimbul/wotan

рдЖрдк TSLint рдирд┐рдпрдореЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдЯрд░ рд░рдирдЯрд╛рдЗрдо ( @fimbul/wotan ) рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдкрдХреЛ рдХреЗрд╡рд▓ @fimbul/heimdall , рджреЗрдЦреЗрдВ https://github.com/fimbullinter/wotan/tree/master/packages/heimdall#readme

Vue рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓рд┐рдВрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, @fimbul/ve (рдХреЛрдИ рдЯрд╛рдЗрдкреЛ рдирд╣реАрдВ, 've' рдореЗрдВ рдХреЛрдИ 'u' рдирд╣реАрдВ рд╣реИ): https://github.com/fimbullinter/wotan/tree/master/packages/ve#readme

рдХреНрдпрд╛ рдХреЛрдИ рд╢реЗрдбреНрдпреВрд▓ рд╣реИ рдЬрдм tslint linting vue/html рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдЧрд╛? @Toilal

рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╕рдореБрджрд╛рдп рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИ, рд▓реЗрдХрд┐рди VueJS рд▓реЗрдЦрдХ Vue-cli (рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЕрд▓реНрдлрд╛ рдореЗрдВ) рдХреЗ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдмрдЬрд╛рдп ESLint рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рдЬрд╛рддрд╛ рд╣реИред

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА [email protected] ред Daud:

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

рдФрд░ рд▓рд┐рдВрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ TSLint рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдХрд▓реНрдк рд╣реЛрдЧрд╛ред

рдореИрдВ рдЗрд╕ рд╕реВрддреНрд░ рдкрд░ рд╕рднреА рдХреЗ рд▓рд┐рдП рдФрд░ рднреА рдмрдбрд╝реА рдЦрд╝рдмрд░реЛрдВ рдХреЗ рд╕рд╛рде рд╡рд╛рдкрд╕ рдЖрдпрд╛ рд╣реВрдБ:

рд╡реЙрдЯрди рдХрд╛ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдЖрдкрдХреЗ 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. Daud
    рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ рдФрд░ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░реЗрдВред рдЙрдкрд▓рдмреНрдз рд╕реАрдПрд▓рдЖрдИ рддрд░реНрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдкрдврд╝реЗрдВред
    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. рдЖрдЧреЗ рдХреА рдкрдврд╛рдИ
    рд╡реЛрдЯрди - рд╕реАрдПрд▓рдЖрдИ рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди: https://github.com/fimbullinter/wotan/tree/master/packages/wotan#readme
    Valt├╜r - TSLint рдирд┐рдпрдореЛрдВ рдФрд░ рд╕реНрд╡рд░реВрдкрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд▓рдЧрдЗрди - "TSLint рд░рдирдЯрд╛рдЗрдо рдЬреЛ TSLint рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИ": https://github.com/fimbullinter/wotan/tree/master/packages/valtyr#readme
    V├й - Vue рдПрдХрд▓ рдлрд╝рд╛рдЗрд▓ рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрд╕реЗрд╕рд░: https://github.com/fimbullinter/wotan/tree/master/packages/ve#readme
    Fimbullinter - рдЖрдкрдХреЛ рдЕрднреА рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП: https://github.com/fimbullinter/wotan#readme
  5. рд▓рд╛рдЗрдХ, рд╢реЗрдпрд░ рдФрд░ рд╕рдмрд╕реНрдХреНрд░рд╛рдЗрдм :рд╕реНрдЯрд╛рд░:

@romandragan

рдЖрдк Vue-loader рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдХреЗ TSLint рдХрд╛ рдЙрдкрдпреЛрдЧ Vue рдПрдХрд▓ рдлрд╝рд╛рдЗрд▓ рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рд╡реЗрдмрдкреИрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдорд╛рдзрд╛рди рд╣реИред рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ, рддреЛ рд╡рд╣рд╛рдБ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╛рдзрд╛рди рд╣реИ рдХрд┐ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдлрд╝рд╛рдЗрд▓реЗрдВ рдирд┐рд░реНрдорд╛рдг рдЙрдкрдХрд░рдг рддрд╛рдХрд┐ рд╣рдо Vue tslint рд╕рдХрддрд╛ рд╣реИ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рд╣реИ рдерд╛ рд╣реЛрдЧрд╛ fusebox (рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдирд┐рд░реНрдорд╛рдг рдЙрдкрдХрд░рдг)ред

рд╡реЗрдмрдкреИрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рд╕рдорд╛рдзрд╛рдиред

рдореИрдВрдиреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд▓реЛрдбрд░ рдмрдирд╛рдпрд╛ рд╣реИ рдЬреЛ vue-loader рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ "рдлрд╝рд╛рдЗрд▓" рд╕реЗ рд╕рднреА рд╕рдлреЗрдж рдЬрдЧрд╣реЛрдВ рдХреЛ рдЯреНрд░рд┐рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдПрдХ рд▓рд┐рдВрдЯрд░ рдХреЗ рд▓рд┐рдП рд╕рдлреЗрдж рд╕реНрдерд╛рди рдЬреЛрдбрд╝рддрд╛ рд╣реИред

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') ],....

рдФрд░ рдлрд┐рд░ рдирд┐рдХрд╛рд▓реЗрдВ-рд╡реНрд╣рд╛рдЯреНрд╕рдПрдк-рдЯреАрдПрд╕-рд▓реЛрдбрд░:
/* 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; }
_рдХреЛрдб рд╕реНрд╡рд░реВрдкрдг рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдорджрдж рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рдХрд┐рдпрд╛_

рдпрд╣ рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдзрдиреНрдпрд╡рд╛рдж

рд╡реИрд╕реЗ рд╣реА рдореИрдВ рдПрдХ рд╣реА рдкреГрд╖реНрда рдкрд░ рд╣реВрдВ, рдХреНрдпрд╛ рдпрд╣ рддрдм рддрдХ рддрдп рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЬрдм рддрдХ рдЗрд╕реЗ рдкреАрдЖрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ?

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ no-consecutive-blank-lines рдЗрд╕ рд╕реЗрдЯрдЕрдк рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ (рдЬреЛ рдПрдХ рдХрд╕реНрдЯрдо рд▓реЛрдбрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП), рдореИрдВ рд╕рд┐рд░реНрдл рдпрд╣ рдиреЛрдЯ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рд╣рд╛рд▓ рдХреЗ рд╡реЗрдмрдкреИрдХ рдФрд░ рд╡реАрдпреВ-рд▓реЛрдбрд░ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рднреА, рдореБрдЭреЗ typeCheck: true рдирд╣реАрдВ рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИ *.vue рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ tslint рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реЗ рдирд╛рдЦреБрд╢ рд╣реИ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ appendTsSuffixTo )ред рдпрд╣ рдбреЗрдореЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рджреЗрддрд╛ рд╣реИред

рдирд┐рд╢рд╛рди

рдпрд╣рд╛рдВ рдХреБрдЫ рдФрд░ рдЦрдмрд░реЗрдВ? рдореИрдВ

рдЕрдЧрд░ рдХреЛрдИ рдЖрдкрдХреА .vue рдлрд╝рд╛рдЗрд▓ рдХреЛ рд▓рд┐рдВрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП cli рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рддреЛ рдЖрдк vue-tslint рдЖрдЬрд╝рдорд╛ рд╕рдХрддреЗ рд╣реИрдВ ред рдпрд╣ рд╕рд╣реА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ ...

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ @romandragan рдХрд╛ рд╕рдорд╛рдзрд╛рди рдЕрдм рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕ рдирд╣реАрдВ рд╣реИ (рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдкрд╣рд▓реЗ рдРрд╕рд╛ рдерд╛)ред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, tslint-loader рдХреЛ рдЕрдкрдиреЗ use рдореЗрдВ \.ts$ рдирд┐рдпрдореЛрдВ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ рдЬреИрд╕реЗ рдЖрдк рд╕рд╛рдорд╛рдиреНрдп рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВ; рдпрд╣ рдЕрдм vue-loader рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ, рдЙрди рд╕рдВрдмрдВрдзрд┐рдд рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЗ рд╡реЗрдмрдкреИрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдЕрдиреБрднрд╛рдЧреЛрдВ рдХреЛ рд╕реМрдВрдкрддрд╛ рд╣реИред рдХреЗ рдкреНрд▓рдЧрдЗрди рдШрдЯрдХ 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 рдХреЛрд░ рдореЗрдВ рдЙрддрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдЧрд╛:

рдпрд╣рд╛рдВ рдЪрд░реНрдЪрд╛ рдпрд╛ рдареЛрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреА рдХрдореА рдФрд░ ESLint (#4534) рдХреЗ рдкрдХреНрд╖ рдореЗрдВ TSLint рдХреЗ рдЖрдЧрд╛рдореА рдмрд╣рд┐рд╖реНрдХрд░рдг рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдореИрдВ рдЖрдЧреЗ рдЬрд╛рдХрд░ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рд╣рд╛рдЙрд╕рдХреАрдкрд┐рдВрдЧ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрдмрдВрдзрд┐рдд 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 рдХреГрдкрдпрд╛ рдЗрд╕ рддрд░рд╣ рдХреЗ рдореБрджреНрджреЛрдВ рдХреЛ рд╡реЙрдЯрди рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рд▓рд╛рдПрдВ, рди рдХрд┐ tslint

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

avanderhoorn picture avanderhoorn  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ghost picture ghost  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

dashmug picture dashmug  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

rajinder-yadav picture rajinder-yadav  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

CSchulz picture CSchulz  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ