vuejs / vetur

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

"import" does not quite work with *.vue SFC #399

Closed jiayexie closed 7 years ago

jiayexie commented 7 years ago

Info

Problem

I'm using Vue@2.4.2 with Typescript@2.4.2. I'm trying to change my existing .ts, .scss, .html files into single file components (.vue). I realized that the type reference stopped working for components converted into SFC.

There are two problems:

  1. The import statement in my .vue script tag loses reference. When I right click on 'myComponent' in import myComponent from ./myComponent, it doesn't give me any option to go to definition, find references etc.
  2. In my other ts files, the import statement for the .vue file does not provide the correct reference or type. I followed the advice in https://github.com/vuejs/vetur/issues/213 and added a definition file like this:
    declare module "*.vue" {
       import Vue from 'vue'
       export default Vue
    }

    but now the 'mySfcComponent' in import mySfcComponent from ./mySfcComponent.vue only takes me to the declaration of Vue, not my component.

Before when I only used ts files to write components, Typescript had no problem referencing components from import statements. Can I have the same experience when I switch to *.vue files with typescript?

HerringtonDarkholme commented 7 years ago

Hi @laputa523.

  1. I wonder if ./myComopnent is a vue file. If it is, you need to write it as ./myComponent.vue. Otherwise I find it works fine. e.g.

    screen shot 2017-08-23 at 10 26 30 am
  2. Sadly, ts files aren't handled by vetur. I recommend you to try https://github.com/sandersn/vue-ts-plugin. VSCode should be aware of the plugin.

jiayexie commented 7 years ago

Thanks @HerringtonDarkholme, vue-ts-plugin seems to solve the problem of referencing ts files from the vue script tag.

However, my other problem is that I'm writing ./myComponent.vue in my ts file but it does not infer the type and I cannot F12 to go to the component .vue file. Is this expected and there's no workaround?

image

HerringtonDarkholme commented 7 years ago

I think vue-ts-plugin should fix definition finding in ts file. hmmm, that's strange.

Also, referencing ts file from vue SFC should work out of box, without vue-ts-plugin.

I would say jumping Vue definition in ts is working as intended.

HerringtonDarkholme commented 7 years ago

Sadly, vue-ts-plugin is broken. Changing ts behavior isn't vetur's target.

You can open an issue in vue-ts-plugin's repo.

How to fix vue-ts-plugin:

first, npm install vue-ts-plugin second, cd to vue-ts-plugin's directory in node_modules, manually tsc it. thrid, remove ts_module require statement, change ts_module to ts. last, remove vue-template-compiler, reinstall vue-template-compiler manually.

HerringtonDarkholme commented 7 years ago

FYI, you can try this plugin.

https://github.com/HerringtonDarkholme/vue-ts-plugin

schoening commented 7 years ago

I would say jumping Vue definition in ts is working as intended.

Sorry but that makes no sense at all to me. Clicking on "go to definition" on an imported component should clearly go to the component file. Not to node_modules/vue/types; especially since it does go to the component file if the file is not a single-file-component.

That is literally how it works for every other file.

I would highly suggest that this is indeed part of veturs job, because as it stands now; either the definition of sfc (pointing to node_modules/vue/types) is incorrect (most likely), or pointing towards the actual file that one has imported and is trying to access is incorrect.. they can't both be right at the same time.

If its a matter of not having enough time to fix this then I am more than willing to help out, this is important to me.

schoening commented 7 years ago

I can understand if its a case of being "out of scope" for the plugin. But I don't think it is working as indented...

HerringtonDarkholme commented 7 years ago

I would highly suggest that this is indeed part of veturs job

Sadly it is not. Vetur can only affect vue file, but not ts file. That would need to change tsserver's behavior.

Also, there is a lot of other altjs files, we don't have enough effort to implement plugins for them.

You can try the plugin I linked above. It's a tsserver plugin and can help you navigate vue file in typescript.

schoening commented 7 years ago

I will give the plugin a try, thanks..

I am still a little stubborn on this however.. Could you tell me what you think is the intended behavior when writing a single-file-component in JavaScript? Is that supposed to go to the component.vue file or not? @HerringtonDarkholme

I just want to make sure we are on the same page with this, I am not trying to be annoying..

Also, there is a lot of other altjs files, we don't have enough effort to implement plugins for them.

That I can understand. Which is the "out of scope" part I mentioned.

schoening commented 7 years ago

Your plugin https://github.com/HerringtonDarkholme/vue-ts-plugin has solved the problem for me. Thank you.