Tslint: Поддержка линтинга vue / html файла

Созданный на 22 янв. 2017  ·  35Комментарии  ·  Источник: palantir/tslint

Запрос функции

  • __TSLint version__: 4.3.1
  • __TypeScript version__: 2.1.5
  • __Запуск TSLint через__: API Node.js

Линтинг кода 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"
    ]
  }
}

Фактическое поведение

Пытается запечатать весь файл, но безуспешно.

Ожидаемое поведение

проверьте код только внутри тегов скрипта, аналогично eslint.

Aged Away Feature Request

Самый полезный комментарий

Еще новости? 🤙

Все 35 Комментарий

@ nrip-monotype, вы можете использовать TSLint с однофайловыми компонентами Vue, настроив vue-loader . Например, в webpack 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>

Цлинт видит как:

    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.

Я также получаю те же no-consecutive-blank-lines ложные срабатывания, что и @lucastheisen и @romandragan.

Я получаю 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-loader и tslint-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 установлены и работают нормально, так как я получаю правильный lint из файлов * .ts.

В качестве обходного пути мы можем отделить логику TypeScript от файла .vue и удалить tslint-loader из загрузчиков vue. Затем no-consecutive-blank-lines исчезает.

@romandragan, это работает, но было бы неплохо добавить код внутри тега <script> : это необходимо для поддержки редактора, и гораздо проще запускать команду tslint отдельно, а не через весь веб-пакет поток.

@adidahiya есть какие-нибудь планы на эту функцию?
или какой-либо план поддержки системы плагинов в tslint, например, плагинов eslint?

Если вы используете Webpack, у меня есть .vue файлы, работающие и линтинг на уровне typechecker без проблем с no-consecutive-blank-lines в fork-ts-checker-webpack-plugin . Вы можете увидеть PR здесь (и npm install из тестовой ветки и использовать его прямо сейчас, см. Начало цепочки PR): https://github.com/Realytics/fork-ts-checker-webpack-plugin / pull / 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 действительно может извлекать JavaScript или TypeScript из файлов vue, поэтому анализ файлов vue не является проблемой для webpack. Однако TSLint по-прежнему выдает сообщение «Недопустимый исходный файл», потому что имена файлов заканчиваются на «.vue», если включен typeCheck ...

Кроме того, мы можем заставить TSLint перестать жаловаться на последовательные пустые строки, разрешив последовательные пустые строки в начале или в конце файлов vue, потому что vue-loader не удаляет строки, не относящиеся к TypeScript, а вместо этого очищает их, чтобы поддерживать правильные номера строк.

В настоящее время я работаю над линтером, который мог бы решить эти проблемы без необходимости в веб-пакете: https://github.com/ajafff/wotan
В настоящее время это доказательство концепции и может или не может быть интегрировано в TSLint. Это полностью переписано с нуля и практически несовместимо с TSLint.

Он имеет возможность преобразовывать файлы с помощью процессора (аналогично процессорам ESLint). Процессор vue извлекает код TypeScript из SFC, линтер только выравнивает код, затем процессор сопоставляет ошибки с правильным местоположением в исходном файле. Это работает даже с проверкой типов.
Вы можете увидеть пример вывода линтинга файла 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 из командной строки отображал TS-часть моих файлов Vue? Он отлично работает в VS Code, но я бы хотел, чтобы командная строка тоже работала.

У меня ушло немного больше времени, чем я думал, но вот оно: https://www.npmjs.com/package/@fimbul/wotan

Вы даже можете использовать среду выполнения линтера ( @fimbul/wotan ) для выполнения правил TSLint. Вам нужно всего лишь @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 будет поддерживать линтинг vue / html файла? @Toilal

Реализовать это должно сообщество, но автор VueJS, похоже, предпочитает плагины ESLint TypeScript вместо последней версии vue-cli (в настоящее время в альфа-версии).

Эта функция, похоже, уже реализована в [email protected] . Запустить:

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

И будет возможность использовать TSLint в качестве линтера.

Я вернулся с еще более интересными новостями для всех в этой теме:

Последняя версия wotan может выполнять правила TSLint в соответствии с вашим tslint.json и добавляет поддержку процессоров. Это означает, что вам не нужно менять свою конфигурацию и вы можете начать линтинг файлов 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 - интерфейс командной строки и конфигурация: 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

вы можете использовать TSLint с однофайловыми компонентами Vue, настроив vue-loader.

Спасибо за решение. Но это просто решение для Webpack. Было бы здорово, если бы существовало общее решение, не зависящее от инструмента сборки, чтобы мы могли tslint файлы Vue, скомпилированные с помощью Fusebox (или любого другого инструмента сборки).

Еще одно решение для webpack.

Я создал простой загрузчик, который обрезает все пробелы из «файла», предоставленного 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') ],....

а затем remove-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; }
_Любая помощь по улучшению форматирования кода приветствуется_

Он отлично работает и позволяет не изменять исходники, спасибо

Так что я нахожусь на той же странице, не будет ли это исправлено, если это не будет сделано в качестве пиара?

Помимо того, что no-consecutive-blank-lines не работает в этой настройке (которую можно обойти с помощью специального загрузчика), я просто отмечаю, что даже с последними версиями webpack и vue-loader я не могу получить typeCheck: true работает с *.vue файлами, потому что tslint недоволен расширением (даже с appendTsSuffixTo ). Этот демонстрационный проект дает простой пример, с которым можно поиграть.

отметка

Еще новости? 🤙

Если кто-то хочет использовать cli для линтинга вашего файла .vue, вы можете попробовать vue-tslint . Не идеально, но работает ...

Обратите внимание, что решение @romandragan теперь не является лучшей практикой (не уверен, было ли так раньше). Вместо этого добавьте tslint-loader к своим use в правилах \.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, пожалуйста,

Была ли эта страница полезной?
0 / 5 - 0 рейтинги