How to auto import Vue components
Tags: vue, unplugin, vite, tutorial
Published: 2024-05-21 21:26:28

## Goal

This article is meant to help you learn how to set up on-demand components auto importing for Vue using [unplugin-vue-components](https://github.com/unplugin/unplugin-vue-components) in a Vue/Vite powered project. _Unplugin supports and Webpack, Rspack, Vue CLI, Rollup and esbuild, but they are not part of this article_ ([Read all unplugin features](https://github.com/unplugin/unplugin-vue-components?tab=readme-ov-file#features))

## Prerequisites

### Setup Vue project
To create a new Vue project using [create-vue](https://github.com/vuejs/create-vue), simply run the following command in your terminal _(instead of npm you can use your favourite package manager e.g. pnpm, yarn or bun)_:
```
npm create vue@latest
```

Now you should see, this prompt window. Pick the options that you would like to have:
![create-vue](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3yjhaga2w8o8j2pzv2y.png)

## Setup
### 1. Install dependency
```
npm i unplugin-vue-components -D
```

### 2. Initialize the plugin in **vite.config.ts**
```
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
    Components({ /* options */ }),
  ],
})
```

#### Typescript support
Typescript support is enabled by default if it's already enabled. Once the setup is done, a **components.d.ts** will be generated and updates automatically with the type definitions.

**components.d.ts**:
```
declare module 'vue' {
  export interface GlobalComponents {
    HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
    IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default']
    IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default']
    IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default']
    IconSupport: typeof import('./src/components/icons/IconSupport.vue')['default']
    IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default']
    RouterLink: typeof import('vue-router')['RouterLink']
    RouterView: typeof import('vue-router')['RouterView']
    TheWelcome: typeof import('./src/components/TheWelcome.vue')['default']
    WelcomeItem: typeof import('./src/components/WelcomeItem.vue')['default']
  }
}
```

> Make sure you also add **components.d.ts** to your tsconfig.json under include.

In our case, we will have to update **tsconfig.app.json** from:
```
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"]
```
to:
```
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "components.d.ts"],
```

### Importing from UI Libraries
**unplugin-vue-components** supports built-in [resolvers](https://github.com/unplugin/unplugin-vue-components?tab=readme-ov-file#importing-from-ui-libraries) for popular UI libraries. But if you need something custom, **unplugin-vue-components** got you covered — you can also write your [own resolver](https://arc.net/l/quote/cfwpdnyj).

### Final adjustments
1. Remove component imports
2. Sometimes the default config may not cover your use case - [Custom configuration](https://github.com/unplugin/unplugin-vue-components?tab=readme-ov-file#configuration)
3. Done - view working [example](https://stackblitz.com/edit/github-ulxupx?file=vite.config.ts,src/components/TheWelcome.vue,src/App.vue,README.md)

### Conclusion
* Easy to set up
* Helps with reducing import statements
* Outstanding Typescript support
* Better dev experience 

### Reference
* [unplugin-vue-components](https://github.com/unplugin/unplugin-vue-components)
* [create-vue](https://github.com/vuejs/create-vue)
* Cover image by [icarusgk/kawaii-tech-logos](https://github.com/icarusgk/kawaii-tech-logos?tab=readme-ov-file)