From e9233dce360a385e4dff3a547946d31a1320a88e Mon Sep 17 00:00:00 2001 From: IlyaL Date: Mon, 24 Feb 2025 20:22:56 +0800 Subject: [PATCH 1/6] feat: add options --- .gitignore | 1 + examples/vite-vue2/vite.config.ts | 1 + examples/vite-vue3/vite.config.ts | 1 + src/types.ts | 10 ++++++++++ 4 files changed, 13 insertions(+) diff --git a/.gitignore b/.gitignore index bbae2f96..bd89a7d7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ node_modules .DS_Store dist .idea +.unimport-components.json components.d.ts diff --git a/examples/vite-vue2/vite.config.ts b/examples/vite-vue2/vite.config.ts index 148b1ac9..24e876ee 100644 --- a/examples/vite-vue2/vite.config.ts +++ b/examples/vite-vue2/vite.config.ts @@ -8,6 +8,7 @@ const config: UserConfig = { Components({ transformer: 'vue2', dts: 'src/components.d.ts', + dumpUnimportComponents: true, }), ], build: { diff --git a/examples/vite-vue3/vite.config.ts b/examples/vite-vue3/vite.config.ts index 926eae87..478ae759 100644 --- a/examples/vite-vue3/vite.config.ts +++ b/examples/vite-vue3/vite.config.ts @@ -37,6 +37,7 @@ const config: UserConfig = { componentPrefix: 'i', }), ], + dumpUnimportComponents: true, }), ], build: { diff --git a/src/types.ts b/src/types.ts index cb43086f..db7f7012 100644 --- a/src/types.ts +++ b/src/types.ts @@ -205,6 +205,16 @@ export interface Options { * @default true */ sourcemap?: boolean + + /** + * Save unimport components 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 `./.unimport-components.json` + * + * @default false + */ + dumpUnimportComponents?: boolean | string } export type ResolvedOptions = Omit< From ac5be69a11d8c3a9f0b62c087005c759b6d77d7a Mon Sep 17 00:00:00 2001 From: IlyaL Date: Mon, 24 Feb 2025 21:09:43 +0800 Subject: [PATCH 2/6] feat: generate components json --- src/core/context.ts | 27 +++++++++++++++++++++++++-- src/core/declaration.ts | 19 +++++++++++++++++++ src/core/unplugin.ts | 6 ++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/core/context.ts b/src/core/context.ts index 317d82ba..e2f26138 100644 --- a/src/core/context.ts +++ b/src/core/context.ts @@ -6,7 +6,7 @@ import process from 'node:process' import { slash, throttle, toArray } from '@antfu/utils' import Debug from 'debug' import { DIRECTIVE_IMPORT_PREFIX } from './constants' -import { writeDeclaration } from './declaration' +import { writeComponentsJson, writeDeclaration } from './declaration' import { searchComponents } from './fs/glob' import { resolveOptions } from './options' import transformer from './transformer' @@ -34,6 +34,7 @@ export class Context { root = process.cwd() sourcemap: string | boolean = true alias: Record = {} + dumpUnimportComponentsPath: string | undefined constructor( private rawOptions: Options, @@ -41,6 +42,16 @@ export class Context { this.options = resolveOptions(rawOptions, this.root) this.sourcemap = rawOptions.sourcemap ?? true this.generateDeclaration = throttle(500, this._generateDeclaration.bind(this), { noLeading: false }) + + if (this.options.dumpUnimportComponents) { + const dumpUnimportComponents = this.options.dumpUnimportComponents === true + ? './.unimport-components.json' + : this.options.dumpUnimportComponents ?? false + + this.dumpUnimportComponentsPath = dumpUnimportComponents + this.generateComponentsJson = throttle(500, this._generateComponentsJson.bind(this), { noLeading: false }) + } + this.setTransformer(this.options.transformer) } @@ -288,7 +299,7 @@ export class Context { if (!this.options.dts) return - debug.declaration('generating') + debug.declaration('generating dts') return writeDeclaration(this, this.options.dts, removeUnused) } @@ -296,6 +307,18 @@ export class Context { this._generateDeclaration(removeUnused) } + _generateComponentsJson(removeUnused = !this._server) { + if (!Object.keys(this._componentNameMap).length) + return + + debug.components('generating components.json') + return writeComponentsJson(this, removeUnused) + } + + generateComponentsJson(removeUnused = !this._server): void { + this._generateComponentsJson(removeUnused) + } + get componentNameMap() { return this._componentNameMap } diff --git a/src/core/declaration.ts b/src/core/declaration.ts index 99a5945e..0d5c0d03 100644 --- a/src/core/declaration.ts +++ b/src/core/declaration.ts @@ -156,3 +156,22 @@ export async function writeDeclaration(ctx: Context, filepath: string, removeUnu if (code !== originalContent) await writeFile(filepath, code) } + +export async function writeComponentsJson(ctx: Context, _removeUnused = false) { + if (!ctx.dumpUnimportComponentsPath) + return + + const components = [ + ...Object.entries({ + ...ctx.componentNameMap, + ...ctx.componentCustomMap, + }).map(([_, { name, as, from }]) => ({ + name: name || 'default', + as, + from, + })), + ...resolveTypeImports(ctx.options.types), + ] + + await writeFile(ctx.dumpUnimportComponentsPath, JSON.stringify(components, null, 2)) +} diff --git a/src/core/unplugin.ts b/src/core/unplugin.ts index e5cb119a..d82663fb 100644 --- a/src/core/unplugin.ts +++ b/src/core/unplugin.ts @@ -48,6 +48,7 @@ export default createUnplugin((options = {}) => { try { const result = await ctx.transform(code, id) ctx.generateDeclaration() + ctx.generateComponentsJson() return result } catch (e) { @@ -69,6 +70,11 @@ export default createUnplugin((options = {}) => { ctx.generateDeclaration() } + if (ctx.options.dumpUnimportComponents && ctx.dumpUnimportComponentsPath) { + if (!existsSync(ctx.dumpUnimportComponentsPath)) + ctx.generateComponentsJson() + } + if (config.build.watch && config.command === 'build') ctx.setupWatcher(chokidar.watch(ctx.options.globs)) }, From 980b1d01c65da25d88fb53ef4fefa70adff3841a Mon Sep 17 00:00:00 2001 From: IlyaL Date: Sun, 13 Apr 2025 21:37:38 +0800 Subject: [PATCH 3/6] feat: rename `dumpUnimportComponents` to `dumpComponentsInfo` --- examples/vite-vue2/vite.config.ts | 2 +- examples/vite-vue3/vite.config.ts | 2 +- src/core/context.ts | 10 +++++----- src/core/declaration.ts | 4 ++-- src/core/unplugin.ts | 4 ++-- src/types.ts | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/vite-vue2/vite.config.ts b/examples/vite-vue2/vite.config.ts index 24e876ee..e703731e 100644 --- a/examples/vite-vue2/vite.config.ts +++ b/examples/vite-vue2/vite.config.ts @@ -8,7 +8,7 @@ const config: UserConfig = { Components({ transformer: 'vue2', dts: 'src/components.d.ts', - dumpUnimportComponents: true, + dumpComponentsInfo: true, }), ], build: { diff --git a/examples/vite-vue3/vite.config.ts b/examples/vite-vue3/vite.config.ts index 478ae759..feaee8ef 100644 --- a/examples/vite-vue3/vite.config.ts +++ b/examples/vite-vue3/vite.config.ts @@ -37,7 +37,7 @@ const config: UserConfig = { componentPrefix: 'i', }), ], - dumpUnimportComponents: true, + dumpComponentsInfo: true, }), ], build: { diff --git a/src/core/context.ts b/src/core/context.ts index e2f26138..a32ec066 100644 --- a/src/core/context.ts +++ b/src/core/context.ts @@ -34,7 +34,7 @@ export class Context { root = process.cwd() sourcemap: string | boolean = true alias: Record = {} - dumpUnimportComponentsPath: string | undefined + dumpComponentsInfoPath: string | undefined constructor( private rawOptions: Options, @@ -43,12 +43,12 @@ export class Context { this.sourcemap = rawOptions.sourcemap ?? true this.generateDeclaration = throttle(500, this._generateDeclaration.bind(this), { noLeading: false }) - if (this.options.dumpUnimportComponents) { - const dumpUnimportComponents = this.options.dumpUnimportComponents === true + if (this.options.dumpComponentsInfo) { + const dumpComponentsInfo = this.options.dumpComponentsInfo === true ? './.unimport-components.json' - : this.options.dumpUnimportComponents ?? false + : this.options.dumpComponentsInfo ?? false - this.dumpUnimportComponentsPath = dumpUnimportComponents + this.dumpComponentsInfoPath = dumpComponentsInfo this.generateComponentsJson = throttle(500, this._generateComponentsJson.bind(this), { noLeading: false }) } diff --git a/src/core/declaration.ts b/src/core/declaration.ts index 0d5c0d03..4fd2c168 100644 --- a/src/core/declaration.ts +++ b/src/core/declaration.ts @@ -158,7 +158,7 @@ export async function writeDeclaration(ctx: Context, filepath: string, removeUnu } export async function writeComponentsJson(ctx: Context, _removeUnused = false) { - if (!ctx.dumpUnimportComponentsPath) + if (!ctx.dumpComponentsInfoPath) return const components = [ @@ -173,5 +173,5 @@ export async function writeComponentsJson(ctx: Context, _removeUnused = false) { ...resolveTypeImports(ctx.options.types), ] - await writeFile(ctx.dumpUnimportComponentsPath, JSON.stringify(components, null, 2)) + await writeFile(ctx.dumpComponentsInfoPath, JSON.stringify(components, null, 2)) } diff --git a/src/core/unplugin.ts b/src/core/unplugin.ts index d82663fb..39616787 100644 --- a/src/core/unplugin.ts +++ b/src/core/unplugin.ts @@ -70,8 +70,8 @@ export default createUnplugin((options = {}) => { ctx.generateDeclaration() } - if (ctx.options.dumpUnimportComponents && ctx.dumpUnimportComponentsPath) { - if (!existsSync(ctx.dumpUnimportComponentsPath)) + if (ctx.options.dumpComponentsInfo && ctx.dumpComponentsInfoPath) { + if (!existsSync(ctx.dumpComponentsInfoPath)) ctx.generateComponentsJson() } diff --git a/src/types.ts b/src/types.ts index db7f7012..9390c8e3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -214,7 +214,7 @@ export interface Options { * * @default false */ - dumpUnimportComponents?: boolean | string + dumpComponentsInfo?: boolean | string } export type ResolvedOptions = Omit< From eef2e0b2dc32f28809c8d1fde614819c7dba95da Mon Sep 17 00:00:00 2001 From: IlyaL Date: Sun, 13 Apr 2025 21:48:06 +0800 Subject: [PATCH 4/6] feat: regenerate `components.json` on HMR --- src/core/context.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/context.ts b/src/core/context.ts index a32ec066..5e5ce85e 100644 --- a/src/core/context.ts +++ b/src/core/context.ts @@ -180,6 +180,7 @@ export class Context { onUpdate(path: string) { this.generateDeclaration() + this.generateComponentsJson() if (!this._server) return From b0490edc19817ef433a475c92173cd13a909c15c Mon Sep 17 00:00:00 2001 From: IlyaL Date: Sun, 13 Apr 2025 21:51:54 +0800 Subject: [PATCH 5/6] feat: rename `.unimport-components.json` to `.components-info.json` --- .gitignore | 2 +- src/core/context.ts | 4 ++-- src/types.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index bd89a7d7..4d637feb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ node_modules .DS_Store dist .idea -.unimport-components.json +.components-info.json components.d.ts diff --git a/src/core/context.ts b/src/core/context.ts index 5e5ce85e..499a9a3b 100644 --- a/src/core/context.ts +++ b/src/core/context.ts @@ -45,7 +45,7 @@ export class Context { if (this.options.dumpComponentsInfo) { const dumpComponentsInfo = this.options.dumpComponentsInfo === true - ? './.unimport-components.json' + ? './.components-info.json' : this.options.dumpComponentsInfo ?? false this.dumpComponentsInfoPath = dumpComponentsInfo @@ -312,7 +312,7 @@ export class Context { if (!Object.keys(this._componentNameMap).length) return - debug.components('generating components.json') + debug.components('generating components-info') return writeComponentsJson(this, removeUnused) } diff --git a/src/types.ts b/src/types.ts index 9390c8e3..588fa3ed 100644 --- a/src/types.ts +++ b/src/types.ts @@ -210,7 +210,7 @@ export interface Options { * Save unimport components 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 `./.unimport-components.json` + * When set to `true`, it will save to `./.components-info.json` * * @default false */ From da24a26ef38ac0d8690b3afb0b43561187d9d064 Mon Sep 17 00:00:00 2001 From: IlyaL Date: Sun, 13 Apr 2025 21:55:29 +0800 Subject: [PATCH 6/6] docs: clarify `dumpComponentsInfo` option description --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 588fa3ed..ac17d1e3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -207,7 +207,7 @@ export interface Options { sourcemap?: boolean /** - * Save unimport components into a JSON file for other tools to consume. + * 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`