vuejs / vetur

Vue tooling for VS Code.
https://vuejs.github.io/vetur/
MIT License
5.75k stars 594 forks source link

Linting support for typescript #170

Open timeu opened 7 years ago

timeu commented 7 years ago

I am not sure, if this issue belongs here or rather in vscode-tslint, but is there any way to add support for linting typescript script blocks (<script lang="ts">) in single file vue components (similar to what is possible with eslint?) or is there any workaround ?

In my current webpack setup, I managed to get linting to work from the command line when I run the build step (can be done with vue-loader and ts-loader). However VSCode does not display the linting errors and warnings.

octref commented 7 years ago

Do you have an example project where I can test it?

If you can get linting to work on CLI I should be able to surface the errors to VSCode.

timeu commented 7 years ago

I created a repo based on vue-cli's official webpack-simple template and replaced javascript with typescript using the vue-loader together with the ts-loader and tslint-loader.

To re-produce:

git clone git@github.com:timeu/vue-typescript-linting.git
cd vue-typescript-linting
npm install 

You also need typescrpt and tslint installed globally. If you run npm run build you will see some warnings from tslint for main.ts and the App.vue file. In Visual Studio Code however only the warnings are displayed for the main.ts file but not for the App.vue file.

Hope this helps

ppasieka commented 7 years ago

I'm not sure if this is supported by tslint. Not yet I guess.

https://github.com/palantir/tslint/issues/2099

timeu commented 7 years ago

@ppasieka: tslint works fine for .vue files in the command line with this setup. The problem is that those lint errors are not surfaced/displayed in visual studio code.

romandrahan commented 7 years ago

@timeu, do you have TSLint no-consecutive-blank-lines error for .vue files in your repo? Cause I have it with my proposed configuration.

timeu commented 7 years ago

@romandragan yeah I have the same issue with no-consecutive-blank-lines, but I guess this is independent of this issue.

octref commented 7 years ago

Actually I'm planning to have better integration between vetur and eslint/tslint by just sending the js/ts region to eslint/tslint and add padding to the errors position. vetur already divides Vue SFC into multiple regions so it has this info.

octref commented 7 years ago

I'll build a tslint-plugin-vue on top of BenoitZugmeyer/eslint-plugin-html, similar to what vuejs/eslint-plugin-vue did.

octref commented 7 years ago

Well tslint doesn't support plugins yet :( I'll see what I can do. Probably will end up sending the TS region to a TSLint LS like this: https://github.com/angelozerr/tslint-language-service

akoidan commented 7 years ago

In webpack I can specify the rule for vue-loader like below. Is there anything I can do to view linting errors from Webstorm? (For .vue files)

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

image

prograhammer commented 7 years ago

I created a VSCode extension for linting TypeScript in .vue files: TSLint Vue

Just make sure you set the language attribute on your script tags: <script lang="ts">...</script>. This is a fork of vscode-tslint which adds .vue ability (and I'm also working on adding linting at the typechecker level for my next release). I'll deprecate the extension once @octref and the awesome Vetur team get linting working.

Cheers!

prograhammer commented 6 years ago

Latest version (v1.1.0) of TSLint Vue now includes linting at typechecker level.

You can turn on linting at the typechecker level by setting the typeCheck tslint option to true in your settings.json (File > Preferences > Settings - Workspace):

// .vscode/settings.json
{

    "tslint.typeCheck": true, 

}

vscode-tslint-vue

I'm also working on a PR in the excellent & fast fork-ts-checker-webpack-plugin to work with .vue files. Hopefully ready later today. (CC @octref)

octref commented 6 years ago

@prograhammer Thanks, I'll look into your plugin to see how I can integrate it (great work!)

If I understand correctly, TSLint Vue is for editor and fork-ts-checker-webpack-plugin is for webpack config so it emits lint error at dev environment, right? We already surface all TS errors so we only need TSLint, but it would be good if the error in editor can be consistent with the error on CLI.

prograhammer commented 6 years ago

@octref The screencapture gif in my previous post shows Vetur working along with TSLint Vue. Vetur is doing a great job at capturing compiler errors (notice the top error on Foo in that gif) and TSLint Vue is able to do linting at the compiler level (I'm using tslint-config-standard in my tslint.json) and catches the no-unused-variables linting rule (as well as the syntax level rule of no semicolon). So this solves the editor situation for the time being! I think you already understood this, but I just wanted to clarify a bit more.

And yes, fork-ts-checker-webpack-plugin is for the webpack build process and doesn't pertain to the editor or vetur. I just mentioned it because likely everyone following this thread will need that too. Now that linting is working in the editor, I'm focused on the webpack build process so we all can get back to work writing vue apps.

Feel free to ping me on any more questions as you decide on what you want to do in Vetur. Thanks!

prograhammer commented 6 years ago

Alright, for anyone following this thread...

I have got TSLint Vue v1.3.0 working fully for .vue files!!! There was a big bug fix where .vue files weren't linting if they weren't found on an import chain of dependencies leading up to a .ts. Now all .vue files lint.

prograhammer commented 6 years ago

Also, if you are looking for a Webpack solution: https://github.com/Realytics/fork-ts-checker-webpack-plugin/pull/77 (Check the top of that PR and you can npm install and try it out right away).

cedeber commented 6 years ago

I didn't test it within vue files, but tslint-language-service works well on typescript files.

w1ndy commented 6 years ago

TypeScript in vue files loses many features compared to pure TypeScript files, like toggling TypeScript server between the one shipped with VSCode and the one installed locally, restarting TypeScript Server, linting, etc. It would be great if vetur can integrate tslint-language-services due to low overhead in comparison with vscode-tslint.

g-plane commented 6 years ago

How about build a eslint-plugin-tslint-errors like eslint-plugin-flowtype-errors?

bbugh commented 6 years ago

Is there a way to disable eslint for lang="ts" blocks only? We have a project with mixed components in TS and JS, and I can't seem to find a way to use tslint for ts and eslint for js. Presently, eslint runs on our ts Vue files and shows errors. ~I'd rather disable eslint for those blocks and have no linting than have incorrect linting errors.~ Because eslint is trying to parse the ts blocks, it won't format the html.

MaartenStaa commented 6 years ago

@bbugh same problem here. I currently have my Typescript Vue files in my eslintignore, and my Javascript Vue files in my tslintignore.

This way the linting of the script works, but I have no linting of the HTML template for my components using Typescript.

acacia314 commented 6 years ago

@bbugh @MaartenStaa I was having this same issue. Not sure what your build set-up is but with the vue-eslint-parser I was able to set up two different parsers for the script section using the eslint glob overrides. I do have to name all my type="ts" files *.ts.vue

eslintrc.js

parser: 'vue-eslint-parser',
  parserOptions: {
    parser: 'babel-eslint',
    ecmaVersion: 2017,
    sourceType: 'module'
  },
"overrides": [
    {
      "files": [ "*.ts.vue" ],
      parser: 'vue-eslint-parser',
        parserOptions: {
          parser: 'typescript-eslint-parser'
        }
    }
  ]

Not sure how this effects the HTML since I'm using Pug and don't get any linting there anyhow.

bbugh commented 6 years ago

@acacia314 that's a nice idea. I don't mind naming our files .ts.vue. I'll give that a shot, thanks for sharing your solution!

zhanba commented 5 years ago

There is a typescript-tslint-plugin made by Microsoft, it works well with .ts file, vetur should try this.

IlCallo commented 5 years ago

@octref

Dunno if you heard about it, but TSLint is going to be deprecated in favor of an ESLint plugin.

I'll leave here some links I found to help setup ESLint with TS support.

https://github.com/typescript-eslint/typescript-eslint https://github.com/microsoft/TypeScript/issues/30553 https://blog.matterhorn.dev/posts/learn-typescript-linting-part-1/

danielwaltz commented 5 years ago

@IlCallo Were you able to get your script blocks (and potentially even template blocks) to catch type errors? I can’t seem to get that working, even though the type errors are shown at compile time from the cli.

I have an example here. If you clone the repo and try passing a number or multiple params to makeExciting() you will not see errors in the editor, but you will see them in the cli when running yarn serve.

EDIT: I answered my own question, it was a configuration option in VSCode. Make sure vetur.validation.script is set to true!

IlCallo commented 5 years ago

Not yet, but I'm not that expert actually, I'm just scratching the surface of linting in these weeks

samlof commented 5 years ago

I got this working too with vue-cli project.

  1. Typescript on with ESlint option for linting. It automatically adds typescript-eslint/parser
  2. Adding the vscode config block from https://vuejs.github.io/vetur/linting-error.html#error-checking to enable vue files
  3. Make sure vetur.validation.script is on
mccoyrjm commented 5 years ago

Thanks @Samlof, I followed your checklist and got it working too!

josh-hemphill commented 4 years ago

Any movement on this, now that Eslint support for typescript is solid is there a way to just continue using prettier-eslint for typescript?

mesqueeb commented 4 years ago

@josh-hemphill I believe TSLint is to be deprecated, so it's better only to rely on ESLint, not TSLint.

josh-hemphill commented 4 years ago

@mesqueeb Yep, that's what I meant.

Also I just saw that Eslint introduced eslint.format.enable so since there's support for prettier-eslint fulling supporting eslint as a formatter should be plug-and-play. Probably not quite that simple, but I'd assume eslint.format.enable means it's now stable to use directly as a standalone formatter. I just switched all of my vscode configs to the following, and I'm loving it, way faster than prettier-eslint. I'll try my hand at making the change myself if I get some time.

    "eslint.format.enable": true,
    "[javascript]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
    },
    "[typescript]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
    },