diff --git a/.gitignore b/.gitignore index bbae2f96..4d637feb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ node_modules .DS_Store dist .idea +.components-info.json components.d.ts diff --git a/examples/vite-vue2/vite.config.ts b/examples/vite-vue2/vite.config.ts index 148b1ac9..e703731e 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', + dumpComponentsInfo: true, }), ], build: { diff --git a/examples/vite-vue3/vite.config.ts b/examples/vite-vue3/vite.config.ts index 926eae87..feaee8ef 100644 --- a/examples/vite-vue3/vite.config.ts +++ b/examples/vite-vue3/vite.config.ts @@ -37,6 +37,7 @@ const config: UserConfig = { componentPrefix: 'i', }), ], + dumpComponentsInfo: true, }), ], build: { diff --git a/src/core/context.ts b/src/core/context.ts index 317d82ba..499a9a3b 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 = {} + dumpComponentsInfoPath: 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.dumpComponentsInfo) { + const dumpComponentsInfo = this.options.dumpComponentsInfo === true + ? './.components-info.json' + : this.options.dumpComponentsInfo ?? false + + this.dumpComponentsInfoPath = dumpComponentsInfo + this.generateComponentsJson = throttle(500, this._generateComponentsJson.bind(this), { noLeading: false }) + } + this.setTransformer(this.options.transformer) } @@ -169,6 +180,7 @@ export class Context { onUpdate(path: string) { this.generateDeclaration() + this.generateComponentsJson() if (!this._server) return @@ -288,7 +300,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 +308,18 @@ export class Context { this._generateDeclaration(removeUnused) } + _generateComponentsJson(removeUnused = !this._server) { + if (!Object.keys(this._componentNameMap).length) + return + + debug.components('generating components-info') + 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..4fd2c168 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.dumpComponentsInfoPath) + 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.dumpComponentsInfoPath, JSON.stringify(components, null, 2)) +} diff --git a/src/core/unplugin.ts b/src/core/unplugin.ts index e5cb119a..39616787 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.dumpComponentsInfo && ctx.dumpComponentsInfoPath) { + if (!existsSync(ctx.dumpComponentsInfoPath)) + ctx.generateComponentsJson() + } + if (config.build.watch && config.command === 'build') ctx.setupWatcher(chokidar.watch(ctx.options.globs)) }, diff --git a/src/types.ts b/src/types.ts index cb43086f..ac17d1e3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -205,6 +205,16 @@ export interface Options { * @default true */ sourcemap?: boolean + + /** + * 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` + * + * @default false + */ + dumpComponentsInfo?: boolean | string } export type ResolvedOptions = Omit< pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy