Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,17 @@ Components({
types: [
/* ... */
],

// Save component information into a JSON file for other tools to consume.
// Provide a filepath to save the JSON file.
// When set to `true`, it will save to `./.components-info.json`
dumpComponentsInfo: false,

// The mode for syncing the components.d.ts and .components-info.json file.
// 'append': only append the new components to the existing files.
// 'overwrite': overwrite the whole existing files with the current components.
// 'default': use 'append' strategy when using dev server, 'overwrite' strategy when using build.
syncMode: 'default',
})
```

Expand Down
11 changes: 7 additions & 4 deletions src/core/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class Context {
private _componentUsageMap: Record<string, Set<string>> = {}
private _componentCustomMap: Record<string, ComponentInfo> = {}
private _directiveCustomMap: Record<string, ComponentInfo> = {}
private _removeUnused = false
private _server: ViteDevServer | undefined

root = process.cwd()
Expand All @@ -42,6 +43,7 @@ export class Context {
this.options = resolveOptions(rawOptions, this.root)
this.sourcemap = rawOptions.sourcemap ?? true
this.generateDeclaration = throttle(500, this._generateDeclaration.bind(this), { noLeading: false })
this._removeUnused = this.options.syncMode === 'overwrite'

if (this.options.dumpComponentsInfo) {
const dumpComponentsInfo = this.options.dumpComponentsInfo === true
Expand Down Expand Up @@ -78,6 +80,7 @@ export class Context {
return

this._server = server
this._removeUnused = this.options.syncMode !== 'append'
this.setupWatcher(server.watcher)
}

Expand Down Expand Up @@ -299,27 +302,27 @@ export class Context {
this._searched = true
}

_generateDeclaration(removeUnused = !this._server) {
_generateDeclaration(removeUnused = this._removeUnused) {
if (!this.options.dts)
return

debug.declaration('generating dts')
return writeDeclaration(this, this.options.dts, removeUnused)
}

generateDeclaration(removeUnused = !this._server): void {
generateDeclaration(removeUnused = this._removeUnused): void {
this._generateDeclaration(removeUnused)
}

_generateComponentsJson(removeUnused = !this._server) {
_generateComponentsJson(removeUnused = this._removeUnused) {
if (!Object.keys(this._componentNameMap).length)
return

debug.components('generating components-info')
return writeComponentsJson(this, removeUnused)
}

generateComponentsJson(removeUnused = !this._server): void {
generateComponentsJson(removeUnused = this._removeUnused): void {
this._generateComponentsJson(removeUnused)
}

Expand Down
1 change: 1 addition & 0 deletions src/core/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const defaultOptions: Omit<Required<Options>, 'include' | 'exclude' | 'ex

sourcemap: true,
dumpComponentsInfo: false,
syncMode: 'default',
prefix: '',
}

Expand Down
10 changes: 10 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,16 @@ export interface Options {
* @default false
*/
dumpComponentsInfo?: boolean | string

/**
* The mode for syncing the components.d.ts and .components-info.json file.
* - `append`: only append the new components to the existing files.
* - `overwrite`: overwrite the whole existing files with the current components.
* - `default`: use `append` strategy when using dev server, `overwrite` strategy when using build.
*
* @default 'default'
*/
syncMode?: 'default' | 'append' | 'overwrite'
}

export type ResolvedOptions = Omit<
Expand Down
24 changes: 23 additions & 1 deletion test/__snapshots__/dts.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ declare module 'vue' {
"
`;

exports[`dts > writeDeclaration - keep unused 1`] = `
exports[`dts > writeDeclaration - append 1`] = `
"/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
Expand All @@ -175,6 +175,28 @@ declare module 'vue' {
"
`;

exports[`dts > writeDeclaration - overwrite 1`] = `
"/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
export {}

/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
TestComp: typeof import('test/component/TestComp')['default']
}
export interface GlobalDirectives {
vLoading: typeof import('test/directive/Loading')['default']
}
}
"
`;

exports[`dts > writeDeclaration 1`] = `
"/* eslint-disable */
// @ts-nocheck
Expand Down
10 changes: 4 additions & 6 deletions test/dts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ const _directive_loading = _resolveDirective("loading")`
expect(await readFile(filepath, 'utf-8')).matchSnapshot()
})

it('writeDeclaration - keep unused', async () => {
const filepath = path.resolve(__dirname, 'tmp/dts-keep-unused.d.ts')
it.each(['append', 'overwrite'] as const)('writeDeclaration - %s', async (syncMode) => {
const filepath = path.resolve(__dirname, 'tmp/dts-test-sync-mode.d.ts')
await writeFile(
filepath,
`
Expand All @@ -70,18 +70,16 @@ declare module 'vue' {
resolvers: resolver,
directives: true,
dts: filepath,
syncMode,
})
const code = `
const _component_test_comp = _resolveComponent("test-comp")
const _directive_loading = _resolveDirective("loading")`
await ctx.transform(code, '')
await ctx._generateDeclaration(false)
await ctx._generateDeclaration()

const contents = await readFile(filepath, 'utf-8')
expect(contents).matchSnapshot()
expect(contents).not.toContain('OldComp')
expect(contents).not.toContain('comment')
expect(contents).toContain('vSome')
})

it('components only', async () => {
Expand Down