Skip to content

Commit 574443a

Browse files
authored
feat: introduce syncMode to control the behavior of generating files (#882)
1 parent ed98de3 commit 574443a

File tree

6 files changed

+56
-11
lines changed

6 files changed

+56
-11
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,17 @@ Components({
465465
types: [
466466
/* ... */
467467
],
468+
469+
// Save component information into a JSON file for other tools to consume.
470+
// Provide a filepath to save the JSON file.
471+
// When set to `true`, it will save to `./.components-info.json`
472+
dumpComponentsInfo: false,
473+
474+
// The mode for syncing the components.d.ts and .components-info.json file.
475+
// 'append': only append the new components to the existing files.
476+
// 'overwrite': overwrite the whole existing files with the current components.
477+
// 'default': use 'append' strategy when using dev server, 'overwrite' strategy when using build.
478+
syncMode: 'default',
468479
})
469480
```
470481

src/core/context.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export class Context {
2929
private _componentUsageMap: Record<string, Set<string>> = {}
3030
private _componentCustomMap: Record<string, ComponentInfo> = {}
3131
private _directiveCustomMap: Record<string, ComponentInfo> = {}
32+
private _removeUnused = false
3233
private _server: ViteDevServer | undefined
3334

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

4648
if (this.options.dumpComponentsInfo) {
4749
const dumpComponentsInfo = this.options.dumpComponentsInfo === true
@@ -78,6 +80,7 @@ export class Context {
7880
return
7981

8082
this._server = server
83+
this._removeUnused = this.options.syncMode !== 'append'
8184
this.setupWatcher(server.watcher)
8285
}
8386

@@ -299,27 +302,27 @@ export class Context {
299302
this._searched = true
300303
}
301304

302-
_generateDeclaration(removeUnused = !this._server) {
305+
_generateDeclaration(removeUnused = this._removeUnused) {
303306
if (!this.options.dts)
304307
return
305308

306309
debug.declaration('generating dts')
307310
return writeDeclaration(this, this.options.dts, removeUnused)
308311
}
309312

310-
generateDeclaration(removeUnused = !this._server): void {
313+
generateDeclaration(removeUnused = this._removeUnused): void {
311314
this._generateDeclaration(removeUnused)
312315
}
313316

314-
_generateComponentsJson(removeUnused = !this._server) {
317+
_generateComponentsJson(removeUnused = this._removeUnused) {
315318
if (!Object.keys(this._componentNameMap).length)
316319
return
317320

318321
debug.components('generating components-info')
319322
return writeComponentsJson(this, removeUnused)
320323
}
321324

322-
generateComponentsJson(removeUnused = !this._server): void {
325+
generateComponentsJson(removeUnused = this._removeUnused): void {
323326
this._generateComponentsJson(removeUnused)
324327
}
325328

src/core/options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const defaultOptions: Omit<Required<Options>, 'include' | 'exclude' | 'ex
2525

2626
sourcemap: true,
2727
dumpComponentsInfo: false,
28+
syncMode: 'default',
2829
prefix: '',
2930
}
3031

src/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,16 @@ export interface Options {
220220
* @default false
221221
*/
222222
dumpComponentsInfo?: boolean | string
223+
224+
/**
225+
* The mode for syncing the components.d.ts and .components-info.json file.
226+
* - `append`: only append the new components to the existing files.
227+
* - `overwrite`: overwrite the whole existing files with the current components.
228+
* - `default`: use `append` strategy when using dev server, `overwrite` strategy when using build.
229+
*
230+
* @default 'default'
231+
*/
232+
syncMode?: 'default' | 'append' | 'overwrite'
223233
}
224234

225235
export type ResolvedOptions = Omit<

test/__snapshots__/dts.test.ts.snap

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ declare module 'vue' {
150150
"
151151
`;
152152

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

178+
exports[`dts > writeDeclaration - overwrite 1`] = `
179+
"/* eslint-disable */
180+
// @ts-nocheck
181+
// Generated by unplugin-vue-components
182+
// Read more: https://github.com/vuejs/core/pull/3399
183+
// biome-ignore lint: disable
184+
export {}
185+
186+
/* prettier-ignore */
187+
declare module 'vue' {
188+
export interface GlobalComponents {
189+
RouterLink: typeof import('vue-router')['RouterLink']
190+
RouterView: typeof import('vue-router')['RouterView']
191+
TestComp: typeof import('test/component/TestComp')['default']
192+
}
193+
export interface GlobalDirectives {
194+
vLoading: typeof import('test/directive/Loading')['default']
195+
}
196+
}
197+
"
198+
`;
199+
178200
exports[`dts > writeDeclaration 1`] = `
179201
"/* eslint-disable */
180202
// @ts-nocheck

test/dts.test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ const _directive_loading = _resolveDirective("loading")`
4848
expect(await readFile(filepath, 'utf-8')).matchSnapshot()
4949
})
5050

51-
it('writeDeclaration - keep unused', async () => {
52-
const filepath = path.resolve(__dirname, 'tmp/dts-keep-unused.d.ts')
51+
it.each(['append', 'overwrite'] as const)('writeDeclaration - %s', async (syncMode) => {
52+
const filepath = path.resolve(__dirname, 'tmp/dts-test-sync-mode.d.ts')
5353
await writeFile(
5454
filepath,
5555
`
@@ -70,18 +70,16 @@ declare module 'vue' {
7070
resolvers: resolver,
7171
directives: true,
7272
dts: filepath,
73+
syncMode,
7374
})
7475
const code = `
7576
const _component_test_comp = _resolveComponent("test-comp")
7677
const _directive_loading = _resolveDirective("loading")`
7778
await ctx.transform(code, '')
78-
await ctx._generateDeclaration(false)
79+
await ctx._generateDeclaration()
7980

8081
const contents = await readFile(filepath, 'utf-8')
8182
expect(contents).matchSnapshot()
82-
expect(contents).not.toContain('OldComp')
83-
expect(contents).not.toContain('comment')
84-
expect(contents).toContain('vSome')
8583
})
8684

8785
it('components only', async () => {

0 commit comments

Comments
 (0)