unplugin / unplugin-vue-components

📲 On-demand components auto importing for Vue
https://www.npmjs.com/package/unplugin-vue-components
MIT License
3.77k stars 349 forks source link

Typescript: component types does not function correctly when unplugin-auto-import is present #640

Open rafael-lua opened 1 year ago

rafael-lua commented 1 year ago

Describe the bug

I just started a fresh project with npm init vue@latest. I installed the plugin latest version and noticed the components are typed as any:

any

Investigating, I thought it could be the new version type change and downgrading to go back to @vue/runtime-core seemed to work again.

However, I noticed the new unplugin-vue-components release did work properly at some point and then stopped. The only other change I did was to also install unplugin-auto-import. And that is what is causing the problem, removing the plugin and deleting the auto-imports.d.ts types made unplugin-vue-components work properly, and the components be correctly typed:

typed

Reproduction

https://github.com/rafael-lua/bug-unplugin-vue-components

System Info

System:
    OS: Linux 5.10 Ubuntu 20.04.5 LTS (Focal Fossa)
    CPU: (4) x64 Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
    Memory: 11.38 GB / 12.45 GB
    Container: Yes
    Shell: 5.8 - /usr/bin/zsh
Binaries:
    Node: 16.16.0 - ~/.nvm/versions/node/v16.16.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v16.16.0/bin/yarn
    npm: 8.11.0 - ~/.nvm/versions/node/v16.16.0/bin/npm

Used Package Manager

npm

Validations

wenfangdu commented 1 year ago

@rafael-lua Try using the workspace ts version and see if the issue persists: image If the issue's gone, try filing an issue in https://github.com/microsoft/TypeScript or https://github.com/vuejs/language-tools.

rafael-lua commented 1 year ago

@rafael-lua Try using the workspace ts version and see if the issue persists: image If the issue's gone, try filing an issue in https://github.com/microsoft/TypeScript or https://github.com/vuejs/language-tools.

I already tried both. Normally, I use the workspace version (5.0.4 - takeover). The issue persists, unfortunately.

wenfangdu commented 1 year ago

@rafael-lua After changing to 5.0.4, did you reload vscode?

rafael-lua commented 1 year ago

@rafael-lua After changing to 5.0.4, did you reload vscode?

Yep. I already tried reloading vscode, volar server, WSL. For both versions (workspace and vscode). And by default I used the workspace version, so it did not work on it from the beginning. It is either downgrade or remove the AutoImport plugin to have it working again (Edit: To be specific, I just need to delete the generated declaration file for AutoImport auto-imports.d.ts for unplugin-vue-components to work again).

wenfangdu commented 1 year ago

@rafael-lua You mean the latest version of unplugin-auto-import and unplugin-vue-components can't work together? If so, what's inside auto-imports.d.ts generated by the latest unplugin-auto-import?

rafael-lua commented 1 year ago

@rafael-lua You mean the latest version of unplugin-auto-import and unplugin-vue-components can't work together? If so, what's inside auto-imports.d.ts generated by the latest unplugin-auto-import?

Yes, that is it. In the repository I provided, these are their versions:

"unplugin-auto-import": "^0.16.4",
"unplugin-vue-components": "^0.25.1",

For what is inside auto-imports.d.ts:

/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-auto-import
export {}
declare global {
  const EffectScope: typeof import('vue')['EffectScope']
  const computed: typeof import('vue')['computed']
  const createApp: typeof import('vue')['createApp']
  const customRef: typeof import('vue')['customRef']
  const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
  const defineComponent: typeof import('vue')['defineComponent']
  const effectScope: typeof import('vue')['effectScope']
  const getCurrentInstance: typeof import('vue')['getCurrentInstance']
  const getCurrentScope: typeof import('vue')['getCurrentScope']
  const h: typeof import('vue')['h']
  const inject: typeof import('vue')['inject']
  const isProxy: typeof import('vue')['isProxy']
  const isReactive: typeof import('vue')['isReactive']
  const isReadonly: typeof import('vue')['isReadonly']
  const isRef: typeof import('vue')['isRef']
  const markRaw: typeof import('vue')['markRaw']
  const nextTick: typeof import('vue')['nextTick']
  const onActivated: typeof import('vue')['onActivated']
  const onBeforeMount: typeof import('vue')['onBeforeMount']
  const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
  const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
  const onDeactivated: typeof import('vue')['onDeactivated']
  const onErrorCaptured: typeof import('vue')['onErrorCaptured']
  const onMounted: typeof import('vue')['onMounted']
  const onRenderTracked: typeof import('vue')['onRenderTracked']
  const onRenderTriggered: typeof import('vue')['onRenderTriggered']
  const onScopeDispose: typeof import('vue')['onScopeDispose']
  const onServerPrefetch: typeof import('vue')['onServerPrefetch']
  const onUnmounted: typeof import('vue')['onUnmounted']
  const onUpdated: typeof import('vue')['onUpdated']
  const provide: typeof import('vue')['provide']
  const reactive: typeof import('vue')['reactive']
  const readonly: typeof import('vue')['readonly']
  const ref: typeof import('vue')['ref']
  const resolveComponent: typeof import('vue')['resolveComponent']
  const shallowReactive: typeof import('vue')['shallowReactive']
  const shallowReadonly: typeof import('vue')['shallowReadonly']
  const shallowRef: typeof import('vue')['shallowRef']
  const toRaw: typeof import('vue')['toRaw']
  const toRef: typeof import('vue')['toRef']
  const toRefs: typeof import('vue')['toRefs']
  const toValue: typeof import('vue')['toValue']
  const triggerRef: typeof import('vue')['triggerRef']
  const unref: typeof import('vue')['unref']
  const useAttrs: typeof import('vue')['useAttrs']
  const useCssModule: typeof import('vue')['useCssModule']
  const useCssVars: typeof import('vue')['useCssVars']
  const useSlots: typeof import('vue')['useSlots']
  const watch: typeof import('vue')['watch']
  const watchEffect: typeof import('vue')['watchEffect']
  const watchPostEffect: typeof import('vue')['watchPostEffect']
  const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for type re-export
declare global {
  // @ts-ignore
  export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
}
// for vue template auto import
import { UnwrapRef } from 'vue'
declare module 'vue' {
  interface ComponentCustomProperties {
    readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
    readonly computed: UnwrapRef<typeof import('vue')['computed']>
    readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
    readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
    readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
    readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
    readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
    readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
    readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
    readonly h: UnwrapRef<typeof import('vue')['h']>
    readonly inject: UnwrapRef<typeof import('vue')['inject']>
    readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
    readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
    readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
    readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
    readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
    readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
    readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
    readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
    readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
    readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
    readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
    readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
    readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
    readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
    readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
    readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
    readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
    readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
    readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
    readonly provide: UnwrapRef<typeof import('vue')['provide']>
    readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
    readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
    readonly ref: UnwrapRef<typeof import('vue')['ref']>
    readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
    readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
    readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
    readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
    readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
    readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
    readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
    readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
    readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
    readonly unref: UnwrapRef<typeof import('vue')['unref']>
    readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
    readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
    readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
    readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
    readonly watch: UnwrapRef<typeof import('vue')['watch']>
    readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
    readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
    readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
  }
}
declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
    readonly computed: UnwrapRef<typeof import('vue')['computed']>
    readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
    readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
    readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
    readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
    readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
    readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
    readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
    readonly h: UnwrapRef<typeof import('vue')['h']>
    readonly inject: UnwrapRef<typeof import('vue')['inject']>
    readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
    readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
    readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
    readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
    readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
    readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
    readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
    readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
    readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
    readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
    readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
    readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
    readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
    readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
    readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
    readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
    readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
    readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
    readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
    readonly provide: UnwrapRef<typeof import('vue')['provide']>
    readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
    readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
    readonly ref: UnwrapRef<typeof import('vue')['ref']>
    readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
    readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
    readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
    readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
    readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
    readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
    readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
    readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
    readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
    readonly unref: UnwrapRef<typeof import('vue')['unref']>
    readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
    readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
    readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
    readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
    readonly watch: UnwrapRef<typeof import('vue')['watch']>
    readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
    readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
    readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
  }
}

That is a big boy, but if I change the plugin config on vite (I removed the imports config), it generates a smaller version that still causes the same issues:

/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-auto-import
export {}
declare global {

}
// for vue template auto import
import { UnwrapRef } from 'vue'
declare module 'vue' {
  interface ComponentCustomProperties {

  }
}
declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {

  }
}
wenfangdu commented 1 year ago

@rafael-lua If you change

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
  }
}

to

declare module 'vue' {
  interface ComponentCustomProperties {
  }
}

Will it work with unplugin-vue-components?

rafael-lua commented 1 year ago

@wenfangdu

In this case, the code would be duplicated, no? Well, I tried changing here, but no results. Tried to remove as well, no good. However, removing the other block and leaving only the @vue/runtime-core, works:

// auto-imports.d.ts
// I removed this:
declare module 'vue' {
  interface ComponentCustomProperties {
  }
}
lincenying commented 1 year ago

See if there is "element-plus/global" in tsconfig.json > compilerOptions > types, if so, you can delete it

rafael-lua commented 1 year ago

@lincenying

Unfortunately, there isn't =/ It is a fresh new project.

wenfangdu commented 1 year ago

@rafael-lua Upgrade these two plugins to 1.8+, and see if the issue persists: image

rafael-lua commented 1 year ago

@wenfangdu

Upgraded, and unfortunately the issue still persists. But instead of any, it shows unknown.

unknown

Alejandro-SB commented 1 year ago

@rafael-lua , in your AutoImport config inside vite.config.ts, you can set dts to something like zzzauto-imports.d.ts and it will work. I guess it takes them in alphabetic order.

rafael-lua commented 1 year ago

@rafael-lua , in your AutoImport config inside vite.config.ts, you can set dts to something like zzzauto-imports.d.ts and it will work. I guess it takes them in alphabetic order.

Wow, you are right, it does.

4350pChris commented 1 year ago

Same issue here! Thanks for the tip, I explicitly include files, so I only had to change the order in tsconfig.json so that the AutoImport typings are included after the components, like so

"include": [
    "components.d.ts",
    "auto-imports.d.ts",
    "src/**/*.ts",
]
lincenying commented 1 year ago

tsconfig.json文件, compilerOptions.types 里的ts文件, 如果包含

declare module '@vue/runtime-core' {
    interface GlobalComponents {
    }
}

这样的, 就会出问题, 把这个文件直接 复制到src目录就正常了, 但是这样有点麻烦, 不知道有没有通用的解决方法

====

tsconfig.json file, the ts file in compilerOptions.types, if it contains

declare module '@vue/runtime-core' {
     interface Global Components {
     }
}

In this way, there will be problems. It is normal to copy this file directly to the src directory, but this is a bit troublesome. I don’t know if there is a general solution

tree-white commented 1 year ago

Same issue here! Thanks for the tip, I explicitly include files, so I only had to change the order in tsconfig.json so that the AutoImport typings are included after the components, like so同样的问题在这里!感谢您的提示,我明确包含文件,所以我只需要更改顺序, tsconfig.json 以便在组件之后包含自动导入类型,如下所示

"include": [
    "components.d.ts",
    "auto-imports.d.ts",
    "src/**/*.ts",
]

我通过配置这个顺序解决了问题...

superrunlong commented 1 year ago

Same issue here! Thanks for the tip, I explicitly include files, so I only had to change the order in tsconfig.json so that the AutoImport typings are included after the components, like so同样的问题在这里!感谢您的提示,我明确包含文件,所以我只需要更改顺序, tsconfig.json 以便在组件之后包含自动导入类型,如下所示

"include": [
    "components.d.ts",
    "auto-imports.d.ts",
    "src/**/*.ts",
]

我通过配置这个顺序解决了问题...

这个真的恶心,我也遇到同样对的问题。 定位到到declare module "vue"冲突,在找配置

oliver139 commented 1 year ago

Same issue here! Thanks for the tip, I explicitly include files, so I only had to change the order in tsconfig.json so that the AutoImport typings are included after the components, like so

"include": [
    "components.d.ts",
    "auto-imports.d.ts",
    "src/**/*.ts",
]

OMG dude, you save my day, thanks!

but it is quite interesting that I have 2 vue projects here with almost the same settings. One of them has auto-imports.d.ts first but having no problem..

warmthsea commented 12 months ago

.npmrc

shamefully-hoist=true
strict-peer-dependencies=false
wiidede commented 9 months ago

Same issue here! Thanks for the tip, I explicitly include files, so I only had to change the order in tsconfig.json so that the AutoImport typings are included after the components, like so

"include": [
    "components.d.ts",
    "auto-imports.d.ts",
    "src/**/*.ts",
]

Wow😲. I have many project using auto import. But only one project needs to specific the order. So weird