Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tsserver running entire .vue files #927

Closed
kaicataldo opened this issue Sep 13, 2017 · 34 comments
Closed

tsserver running entire .vue files #927

kaicataldo opened this issue Sep 13, 2017 · 34 comments

Comments

@kaicataldo
Copy link

kaicataldo commented Sep 13, 2017

Hi! First off, thanks for all your work on ale. I love how everything just works out of the box!

I use TypeScript in Vue single file component (.vue) files. tsserver currently reports a bunch of errors because it is checking the entire contents of the file, rather than just the contents of the script tag (as is expected).

Is there any way we could have it only check the contents of that tag? I know that might be out of the scope of this project. I believe other editor integrations run JavaScript/TypeScript linters on the contents of those tags only (unless ESLint is configured with a plugin to parse the template tag contents as well).

I'd be happy to try to take a look at this if someone could point me in the right direction (though I'm not too familiar with VimScript). Thanks!

My ale .vimrc config:

let g:ale_lint_on_text_changed = 'never'
let g:ale_echo_msg_format = '%linter%: %s'
let g:ale_linters = {
  \ 'javascript': ['eslint', 'flow'],
  \ 'typescript': ['eslint', 'tslint', 'tsserver'],
  \ 'vue': ['eslint', 'stylelint', 'tsserver'],
  \ 'php': ['phpcs'],
  \ 'html': []
\ }
let g:ale_linter_aliases = {'vue': ['css', 'javascript', 'typescript']}

Results of :ALEInfo:

 Current Filetype: vue
Available Linters: ['csslint', 'stylelint', 'eslint', 'flow', 'jscs', 'jshint', 'standard', 'xo', 'eslint', 'tslint', 'tsserver', 'typecheck']
  Enabled Linters: ['stylelint', 'eslint', 'tsserver']
 Linter Variables:
 Global Variables:
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%linter%: %s'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {}
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'never'
let g:ale_linter_aliases = {'vue': ['css', 'javascript', 'typescript']}
let g:ale_linters = {'typescript': ['eslint', 'tslint', 'tsserver'], 'vue': ['eslint', 'stylelint', 'tsserver'], 'php': ['phpcs'], 'html': [], 'javascript': [
'eslint', 'flow']}
let g:ale_open_list = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_offset = 1000000
let g:ale_sign_warning = '--'
let g:ale_statusline_format = ['%d error(s)', '%d warning(s)', 'OK']
let g:ale_warn_about_trailing_whitespace = 1
  Command History:
(started) ['/usr/local/bin/zsh', '-c', '/Users/cataldo/Work/behance/pro2-ui/node_modules/.bin/stylelint  --stdin-filename ''/Users/cataldo/Work/behance/pro2-u
i/app/js/components/ui/BackSpin.vue'' < ''/var/folders/c0/s_2jpbsj39zg_tbt9tsjm4rh0000gn/T/nvimpnXIsd/2/BackSpin.vue''']
(started) ['/usr/local/bin/zsh', '-c', '''/Users/cataldo/Work/behance/pro2-ui/node_modules/eslint/bin/eslint.js'' -f unix --stdin --stdin-filename ''/Users/ca
taldo/Work/behance/pro2-ui/app/js/components/ui/BackSpin.vue'' < ''/var/folders/c0/s_2jpbsj39zg_tbt9tsjm4rh0000gn/T/nvimpnXIsd/3/BackSpin.vue''']
(started) ['/usr/local/bin/zsh', '-c', '/Users/cataldo/Work/behance/pro2-ui/node_modules/.bin/tsserver']
(finished - exit code 0) ['/usr/local/bin/zsh', '-c', '/Users/cataldo/Work/behance/pro2-ui/node_modules/.bin/stylelint  --stdin-filename ''/Users/cataldo/Work
/behance/pro2-ui/app/js/components/ui/BackSpin.vue'' < ''/var/folders/c0/s_2jpbsj39zg_tbt9tsjm4rh0000gn/T/nvimpnXIsd/6/BackSpin.vue''']
<<<OUTPUT STARTS>>>
Deprecation Warning: 'declaration-block-properties-order'has been deprecated and in 8.0 will be removed. Instead use the community 'stylelint-order' plugin pa
ck. See: https://stylelint.io/user-guide/rules/declaration-block-properties-order/
Deprecation Warning: 'selector-no-empty' has been deprecated and in 8.0 will be removed. See: https://stylelint.io/user-guide/rules/selector-no-empty/
<<<OUTPUT ENDS>>>
(finished - exit code 0) ['/usr/local/bin/zsh', '-c', '''/Users/cataldo/Work/behance/pro2-ui/node_modules/eslint/bin/eslint.js'' -f unix --stdin --stdin-filen
ame ''/Users/cataldo/Work/behance/pro2-ui/app/js/components/ui/BackSpin.vue'' < ''/var/folders/c0/s_2jpbsj39zg_tbt9tsjm4rh0000gn/T/nvimpnXIsd/7/BackSpin.vue''
']
<<<NO OUTPUT RETURNED>>>
@w0rp
Copy link
Member

w0rp commented Sep 13, 2017

It's probably checking your file as TypeScript code because your filetype is something like typescript.vue. Or is something else reporting errors? Include the output of :ALEInfo like the issue template said.

@kaicataldo
Copy link
Author

Sure, sorry about that - I thought it was a feature request, didn't realize it was something that was already sorted out! Updated the original comment with my .vimrc config and the output of :ALEInfo.

@w0rp
Copy link
Member

w0rp commented Sep 13, 2017

I don't know how to handle this, but I'll mark this as an enhancement which can be worked on at some point in the future. The way tsserver works, you send an entire TypeScript file to the server and it gives you some diagnostics. It doesn't expect you to send anything else.

@kaicataldo
Copy link
Author

kaicataldo commented Sep 13, 2017

@w0rp Right, makes sense, and that's what I'd expect it to do :) .vue files are a special case (which is why I was wondering if this is maybe out of the scope of this project), but it would be amazing if we could get it working. And I'd be happy to try!

@w0rp
Copy link
Member

w0rp commented Sep 13, 2017

If you can come up with something that'll work, give it a go. 👍

@dfee
Copy link

dfee commented Sep 28, 2017

@kaicataldo any luck with your attempts?

@kaicataldo
Copy link
Author

I unfortunately haven't had time to look into this yet. Still on my backlog of things to do! But if someone else can get to it first, please feel free.

@dfee
Copy link

dfee commented Sep 28, 2017

Ok, so this becomes a somewhat complex issue as tsc the typescript checker, cannot check individual files and use a config file.

Therefore, the only way I can see to use typescript is to parse the file on the way in, and on the way out (either through vim or some intermediate script).

I'm not an expert here, so maybe @w0rp could provide some insight. Let's say I wrote a python or python3 compatible program to do this. I understand that vim supports Python scripts, but is there a "pluggable" way to provide some kind of middleware or wrapper around either tslint or ale so that this program can filter the input or output?

@w0rp
Copy link
Member

w0rp commented Sep 29, 2017

To clarify, the tsc commandline tool isn't used by ALE, tsserver is. Many things are possible, but only a few things are sane. tsserver isn't designed to parse Vue files. I don't know what other editors check Vue files with tsserver, or how they do it.

@kaicataldo
Copy link
Author

Here's a popular Vue plugin for VS Code (it works really well!): https://github.com/vuejs/vetur

Might be able to glean some info from that.

@w0rp
Copy link
Member

w0rp commented Sep 30, 2017

Maybe someone who works with Vue could do something similar to whatever it is that does.

@archseer
Copy link
Contributor

For anyone trying to get this to work with Vue:

I had to install ts-vue-plugin from npm which is this up to date fork: https://github.com/HerringtonDarkholme/vue-ts-plugin

Need to add it to your tsconfig.json:

{
  compilerOptions: {
    "allowSyntheticDefaultImports": true,
    "plugins": [{ "name": "ts-vue-plugin" }]
  }
}

Then, I configured Ale to pick up vue as typescript:

let g:ale_linter_aliases = {'vue': 'typescript'}
let g:ale_linters = {'vue': ['tsserver', 'eslint']}
let g:ale_fixers = {'vue': ['eslint']}

Voila, typechecking for vue files!

@w0rp
Copy link
Member

w0rp commented Mar 22, 2018

I'll close this. That seems like the solution. You could also alias vue to multiple filetypes, if you want to use linters for other filetypes, like html.

@w0rp w0rp closed this as completed Mar 22, 2018
@kaicataldo
Copy link
Author

Awesome! Thanks for the solution @archseer.

@cj
Copy link

cj commented Apr 24, 2018

@archseer this almost works for me, except it doesn't seem to see my tsconfig.json file in the current dir.

@archseer
Copy link
Contributor

@cj I've come across the same thing I think, it doesn't run with the same tsconfig settings as vue-cli or Vetur would. Possibly related #1459

I narrowed it down further but forgot by now, I think it had something to do with the linter being ran on a single file instead of the project (with project-wide settings)

joshukraine added a commit to joshukraine/dotfiles that referenced this issue Jun 21, 2018
@dustinblackman
Copy link

@archseer I see you've used eslint in your example, have you managed to get tslint to work correctly?

@archseer
Copy link
Contributor

archseer commented Aug 9, 2018

@cj Found a temporary patch vuejs/vetur#815

This comment worked for me vuejs/vetur#815 (comment)

@dustinblackman I've had tslint working before but switched to eslint because of eslin-plugin-vue.

@andreav
Copy link

andreav commented Oct 25, 2018

Hello,
I installed ALE and followed instructions from @archseer but with no luck.
@lmiller1990 and me tried to understand why in this thread but without success.
The strange thing is that if I put:

let g:ale_linter_aliases = {'vue': 'typescript'}

I get an error like this:

Error detected while processing function ale#events#SaveEvent[13]..ale#Queue[32]..ale#linter#Get[5]..ale#linter#ResolveFiletype[1]..<SNR>93_Get
AliasedFiletype:
line   17:
E715: Dictionary required

All ALEInfo, packages.json, some pices of vimrc, are written in that thread and I do not repeat here just to keep clean this thread.

Any help is appreciated.

@w0rp
Copy link
Member

w0rp commented Oct 26, 2018

https://github.com/posva/vim-vue/blob/master/ftplugin/vue.vim

This plugin is screwing things up again. I'll fix this by allowing b:ale_linter_aliases to be set to a String for buffers.

@w0rp
Copy link
Member

w0rp commented Oct 26, 2018

You should also delete your g:ale_linter_aliases variable, and stick with the default of ['vue', 'typescript'] in that plugin instead.

@w0rp
Copy link
Member

w0rp commented Oct 26, 2018

b:ale_linter_aliases can now be set to a String, in case a default value is taken from a key in g:ale_linter_aliases. You should delete your g:ale_linter_aliases key, and prefer using b:ale_linter_aliases in ftplugin files instead.

@lmiller1990
Copy link

Woah, @w0rp is a superstar. Great job on this plugin.

@andreav
Copy link

andreav commented Oct 26, 2018

Thank you.
I removed my g:ale_linter_aliases and I let vim-vue set its default b:ale_linter_aliases ['vue', 'javascript']

From ALEInfo now I see

Enabled Linters: ['eslint', 'tsserver']

However I'm continuing linting the whole vue file.

I noticed the ts-vue-plugin folder under node_modules quite empty (at least there is no index.js file as in the repository) maybe this is the problem?

andreav@andreav-pc$ find  node_modules/ts-vue-plugin/
node_modules/ts-vue-plugin/
node_modules/ts-vue-plugin/README.md
node_modules/ts-vue-plugin/LICENSE
node_modules/ts-vue-plugin/package.json

@lmiller1990
Copy link

Maybe that's the problem. I got this:

find  node_modules/ts-vue-plugin/
node_modules/ts-vue-plugin/
node_modules/ts-vue-plugin//LICENSE
node_modules/ts-vue-plugin//bin
node_modules/ts-vue-plugin//bin/index.js
node_modules/ts-vue-plugin//README.md
node_modules/ts-vue-plugin//package.json

You seem to be missing the bin dir. Reinstall? Or even rm -rf node_modules and just yarn again.

@andreav
Copy link

andreav commented Oct 27, 2018

Yes it works!
Thank you so much @lmiller1990 and @w0rp!

@doits
Copy link
Contributor

doits commented Mar 14, 2019

Not exactly the same problem, but related: I'm using ale and ts-vue-plugin and it correctly makes tsserver only lint the script part of my .vue files. So far so good, thanks for this! It also correctly reports type errors when I've done something stupid :-)

The only thing which does not work is resolving imports: I always get a module not found lint error for every component import. For example I have a .vue file which imports another component ...

import Component from "@/components/Component.vue"

... and I get the error ...

2307: Cannot find module '@/components/Component.vue'.

I also tried with relative imports (./ instead of @) and even absolute imports (/path/to/component/Component.vue) to rule out it has something to do with the alias, but it still complains.

The whole project compiles fine though, so this error only happens on linting inside vim with ale and tsserver. Is there something I'm missing? Should I open a new issue for this?

@andreav
Copy link

andreav commented Mar 14, 2019

Same here, and I confirm it is just a linting problem.

@doits
Copy link
Contributor

doits commented Mar 15, 2019

Deleted - it was a misconfiguration on my side, please ignore it ... in regular .ts files imports work as expected.

@doits
Copy link
Contributor

doits commented Mar 15, 2019

I think I found a hint to the solution, it is a problem with ts-vue-plugin. It seems to be that getExternalFiles only returns imported files from .ts files, but not .vue components.

ryo7000/vue-ts-plugin@e4f7c8c tries to fix it afaik, and the error goes away. Though with it I don't get a linting for an invalid .vue import, e.g.

import Component from "@/components/Component.vue" // no linting error, :+1:

import NotExistent from "@/components/wrongNameComponent.vue"
// no linting error even though the file does not exist

import NotExistent from "@/something/wrongName" // no .vue component
// correct linting error about module not found

Looks like all .vue imports are considered valid then, not sure exactly why.

Though in the case with an invalid .vue import the project does not compile, so this will be noticed for sure (even though there is no linting error).

I think this definitely better than wrong linting errors.

All in all looks like there's an update needed for ts-vue-plugin and it has nothing to do with ale, sorry for the noise @w0rp

@w0rp
Copy link
Member

w0rp commented Mar 15, 2019

Okay. Someone else might find the information useful.

@FuDesign2008
Copy link

I think I found a hint to the solution, it is a problem with ts-vue-plugin. It seems to be that getExternalFiles only returns imported files from .ts files, but not .vue components.

ryo7000/vue-ts-plugin@e4f7c8c tries to fix it afaik, and the error goes away. Though with it I don't get a linting for an invalid .vue import, e.g.

import Component from "@/components/Component.vue" // no linting error, :+1:

import NotExistent from "@/components/wrongNameComponent.vue"
// no linting error even though the file does not exist

import NotExistent from "@/something/wrongName" // no .vue component
// correct linting error about module not found

Looks like all .vue imports are considered valid then, not sure exactly why.

Though in the case with an invalid .vue import the project does not compile, so this will be noticed for sure (even though there is no linting error).

I think this definitely better than wrong linting errors.

All in all looks like there's an update needed for ts-vue-plugin and it has nothing to do with ale, sorry for the noise @w0rp

Meet to the same problem.

Is there a solution to fix it ?

@nbl7
Copy link

nbl7 commented Apr 29, 2021

I managed to make it work by installing vls as dev dependency of my project

npm i --save-dev vls
yarn add --dev vls

and in my .vimrc

let g:ale_linters = {'vue': ['vls']}

For the syntax highlighting I use
https://github.com/posva/vim-vue
and
https://github.com/Quramy/tsuquyomi-vue

@PickRelated
Copy link

PickRelated commented May 1, 2021

@nbl7 Thanks bud! You saved my day! I assume you have this in your config file?

let g:ale_vue_eslint_use_global = 0

Because installing vls as a dependency just because you are using vim might not be a good idea. However, it works for me if installed globally. And my g:ale_vue_eslint_use_global is not set to anything, so it uses default value of 1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests