Skip to content

Commit 857a5ae

Browse files
committed
feat: support type only global components
1 parent 6b4ac91 commit 857a5ae

File tree

15 files changed

+101
-23
lines changed

15 files changed

+101
-23
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,33 @@ Components({
238238

239239
If you successfully configured other UI libraries, please feel free to contribute and help others using them out-of-box. Thanks!
240240

241+
## Types for global registered components
242+
243+
Some libraries might register some global components for you to use anywhere (e.g. Vue Router provides `<RouterLink>` and `<RouterView>`). Since they are global available, there is no need for this plugin to import them. However, those are commonly not TypeScript friendly, and you might need to register their types manually.
244+
245+
Thus `unplugin-vue-components` provided a way to only register types for global components.
246+
247+
```ts
248+
Components({
249+
dts: true,
250+
types: [{
251+
from: 'vue-router',
252+
names: ['RouterLink', 'RouterView'],
253+
}],
254+
})
255+
```
256+
257+
So the `RouterLink` and `RouterView` will be presented in `components.d.ts`.
258+
259+
By default, `unplugin-vue-components` detects supported libraries automatically (e.g. `vue-router`) when their are installed in the workspace. If you want to disable it completely, you can pass an empty array to it:
260+
261+
```ts
262+
Components({
263+
// Disable type only registration
264+
types: [],
265+
})
266+
```
267+
241268
## Migrate from `vite-plugin-components`
242269

243270
`package.json`

examples/vite-vue3/components.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
// We suggest you to commit this file into source control
33
// Read more: https://github.com/vuejs/vue-next/pull/3399
44

5-
declare module 'vue' {
5+
declare module '@vue/runtime-core' {
66
export interface GlobalComponents {
77
Avatar: typeof import('./src/components/global/avatar.vue')['default']
88
Book: typeof import('./src/components/book/index.vue')['default']
9-
CarbonSvg: typeof import('./src/components/CarbonSvg.svg?component')['default']
109
ComponentA: typeof import('./src/components/ComponentA.vue')['default']
1110
ComponentAsync: typeof import('./src/components/ComponentAsync.vue')['default']
1211
ComponentB: typeof import('./src/components/ComponentB.vue')['default']
@@ -21,6 +20,8 @@ declare module 'vue' {
2120
MarkdownB: typeof import('./src/components/MarkdownB.md')['default']
2221
MyCustom: typeof import('./../../../../../../src/CustomResolved.vue')['default']
2322
Recursive: typeof import('./src/components/Recursive.vue')['default']
23+
RouterLink: typeof import('vue-router')['RouterLink']
24+
RouterView: typeof import('vue-router')['RouterView']
2425
UiButton: typeof import('./src/components/ui/button.vue')['default']
2526
UiNestedCheckbox: typeof import('./src/components/ui/nested/checkbox.vue')['default']
2627
VanRadio: typeof import('vant/es')['Radio']

examples/vite-vue3/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
"vite": "^2.9.1",
2222
"vite-plugin-inspect": "^0.4.3",
2323
"vite-plugin-md": "^0.12.4",
24-
"vite-plugin-vue-svg": "^0.1.0"
24+
"vue-router": "^4.0.14"
2525
}
2626
}

examples/vite-vue3/src/App.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ const radio = ref('1')
5050
<div class="block">
5151
<h1>Custom Resolvers (1)</h1>
5252
<MyCustom />
53-
<CarbonSvg />
5453
</div>
5554

5655
<div class="block">

examples/vite-vue3/src/components/CarbonSvg.svg

Lines changed: 0 additions & 7 deletions
This file was deleted.

examples/vite-vue3/tsconfig.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
{
2-
"extends": "../../tsconfig"
2+
"extends": "../../tsconfig",
3+
"compilerOptions": {
4+
"types": ["unplugin-icons/types/vue"]
5+
}
36
}

examples/vite-vue3/vite.config.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import { VantResolver } from 'unplugin-vue-components/resolvers'
66
import Markdown from 'vite-plugin-md'
77
import Icons from 'unplugin-icons/vite'
88
import IconsResolver from 'unplugin-icons/resolver'
9-
// @ts-expect-error missing types
10-
import SVG from 'vite-plugin-vue-svg'
119
import Inspect from 'vite-plugin-inspect'
1210

1311
const config: UserConfig = {
@@ -21,15 +19,13 @@ const config: UserConfig = {
2119
include: [/\.vue$/, /\.md$/],
2220
}),
2321
Markdown(),
24-
SVG(),
2522
Icons(),
2623
Inspect(),
2724
Components({
2825
extensions: ['vue', 'md', 'svg'],
2926
directoryAsNamespace: true,
3027
dts: true,
3128
globalNamespaces: ['global'],
32-
importPathTransform: path => path.endsWith('.svg') ? `${path}?component` : undefined,
3329
include: [/\.vue$/, /\.md$/],
3430
resolvers: [
3531
(name) => {

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/core/declaration.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { existsSync, promises as fs } from 'fs'
33
import { notNullish, slash } from '@antfu/utils'
44
import type { Context } from './context'
55
import { getTransformedPath } from './utils'
6+
import { resolveTypeImports } from './type-imports/detect'
67

78
export function parseDeclaration(code: string): Record<string, string> {
89
if (!code)
@@ -12,10 +13,13 @@ export function parseDeclaration(code: string): Record<string, string> {
1213

1314
export async function generateDeclaration(ctx: Context, root: string, filepath: string, removeUnused = false): Promise<void> {
1415
const imports: Record<string, string> = Object.fromEntries(
15-
Object.values({
16-
...ctx.componentNameMap,
17-
...ctx.componentCustomMap,
18-
})
16+
[
17+
...Object.values({
18+
...ctx.componentNameMap,
19+
...ctx.componentCustomMap,
20+
}),
21+
...resolveTypeImports(ctx.options.types),
22+
]
1923
.map(({ path, name, importName }) => {
2024
if (!name)
2125
return undefined

src/core/options.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { join, resolve } from 'path'
22
import { slash, toArray } from '@antfu/utils'
33
import { isPackageExists } from 'local-pkg'
44
import type { ComponentResolver, ComponentResolverObject, Options, ResolvedOptions } from '../types'
5+
import { detectTypeImports } from './type-imports/detect'
56

6-
export const defaultOptions: Omit<Required<Options>, 'include' | 'exclude' | 'transformer' | 'globs' |'directives'> = {
7+
export const defaultOptions: Omit<Required<Options>, 'include' | 'exclude' | 'transformer' | 'globs' | 'directives' | 'types'> = {
78
dirs: 'src/components',
89
extensions: 'vue',
910
deep: true,
@@ -28,6 +29,10 @@ export function resolveOptions(options: Options, root: string): ResolvedOptions
2829
resolved.resolvers = normalizeResolvers(resolved.resolvers)
2930
resolved.extensions = toArray(resolved.extensions)
3031

32+
if (!resolved.types)
33+
resolved.types = detectTypeImports()
34+
resolved.types = resolved.types || []
35+
3136
if (resolved.globs) {
3237
resolved.globs = toArray(resolved.globs).map((glob: string) => slash(resolve(root, glob)))
3338
resolved.resolvedDirs = []

0 commit comments

Comments
 (0)