Skip to content

Commit

Permalink
feat: add option genComponentUsedPath
Browse files Browse the repository at this point in the history
  • Loading branch information
furina-lu committed Dec 26, 2024
1 parent a4c0b89 commit 8ecf321
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 5 deletions.
1 change: 0 additions & 1 deletion examples/vite-vue3/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ declare module 'vue' {
export interface GlobalComponents {
Avatar: typeof import('./src/components/global/avatar.vue')['default']
Book: typeof import('./src/components/book/index.vue')['default']
CollapseCollapseFolderAndCollapseFolderAndComponentPrefixes: typeof import('./src/components/collapse/collapseFolderAnd/CollapseFolderAndComponentPrefixes.vue')['default']
CollapseCollapseFolderCollapseFolderAndComponentFromRoot: typeof import('./src/components/collapse/collapseFolder/CollapseFolderAndComponentFromRoot.vue')['default']
CollapseCollapseFolderFolderAndComponentPartially: typeof import('./src/components/collapse/collapseFolder/FolderAndComponentPartially.vue')['default']
ComponentA: typeof import('./src/components/ComponentA.vue')['default']
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "ComponentA": ["/src/App.vue", "/src/components/MarkdownB.md"], "ComponentB": ["/src/App.vue", "/src/components/ComponentD.vue"], "ComponentC": ["/src/App.vue"], "ComponentD": ["/src/App.vue"], "Recursive": ["/src/App.vue"], "Book": ["/src/App.vue"], "UiButton": ["/src/App.vue"], "UiNestedCheckbox": ["/src/App.vue"], "Avatar": ["/src/App.vue"], "MarkdownA": ["/src/App.vue"], "MarkdownB": ["/src/App.vue"], "MyCustom": ["/src/App.vue"], "IFaSolidDiceFive": ["/src/App.vue"], "IHeroiconsOutlineMenuAlt2": ["/src/App.vue"], "IRiApps2Line": ["/src/App.vue"], "IMdi:diceD12": ["/src/App.vue"], "IMdiLightAlarm": ["/src/App.vue"] }
5 changes: 5 additions & 0 deletions examples/vite-vue3/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ const config: UserConfig = {
componentPrefix: 'i',
}),
],
genComponentUsedPath: {
enable: true,
exclude: [/Van\w+/],
genFilePath: './unplugin-vue-component-used-path_rename.json',
},
}),
],
build: {
Expand Down
2 changes: 1 addition & 1 deletion src/core/declaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ declare module 'vue' {`
return code
}

async function writeFile(filePath: string, content: string) {
export async function writeFile(filePath: string, content: string) {
await mkdir(dirname(filePath), { recursive: true })
return await writeFile_(filePath, content, 'utf-8')
}
Expand Down
13 changes: 12 additions & 1 deletion src/core/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { ComponentResolver, ComponentResolverObject, Options, ResolvedOptio
import { join, resolve } from 'node:path'
import { slash, toArray } from '@antfu/utils'
import { getPackageInfoSync, isPackageExists } from 'local-pkg'
import { writeFile } from './declaration'
import { componentUsedMap } from './transforms/component'
import { detectTypeImports } from './type-imports/detect'

export const defaultOptions: Omit<Required<Options>, 'include' | 'exclude' | 'excludeNames' | 'transformer' | 'globs' | 'directives' | 'types' | 'version'> = {
Expand All @@ -17,7 +19,11 @@ export const defaultOptions: Omit<Required<Options>, 'include' | 'exclude' | 'ex
resolvers: [],

importPathTransform: v => v,

genComponentUsedPath: {
enable: false,
genFilePath: './unplugin-vue-component-used-path.json',
exclude: [],
},
allowOverrides: false,
}

Expand Down Expand Up @@ -93,3 +99,8 @@ function getVueVersion(root: string): 2 | 2.7 | 3 {
return 2
return 3
}

export function genComponentUsedPath(options: Options) {
Object.keys(componentUsedMap).map(key => componentUsedMap[key] = [...componentUsedMap[key]])
writeFile(options.genComponentUsedPath?.genFilePath || './unplugin-vue-component-used-path.json', JSON.stringify(componentUsedMap))
}
20 changes: 19 additions & 1 deletion src/core/transforms/component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import type MagicString from 'magic-string'
import type { SupportedTransformer } from '../..'
import type { IGenComponentUsedPathOnBuildEndOptions } from '../../types'
import type { Context } from '../context'
import type { ResolveResult } from '../transformer'
import process from 'node:process'
import Debug from 'debug'
import { pascalCase, stringifyComponentImport } from '../utils'
import { isExclude, pascalCase, stringifyComponentImport } from '../utils'

const debug = Debug('unplugin-vue-components:transform:component')
export const componentUsedMap: Record<string, any> = {}

function collectComponentUsedPath(component: any, sfcPath: any, options: IGenComponentUsedPathOnBuildEndOptions) {
if (isExclude(component.as, options.exclude))
return

if (!componentUsedMap[component.as]) {
componentUsedMap[component.as] = new Set()
componentUsedMap[component.as].add(sfcPath)
}
else {
componentUsedMap[component.as].add(sfcPath)
}
}
function resolveVue2(code: string, s: MagicString) {
const results: ResolveResult[] = []
for (const match of code.matchAll(/\b(_c|h)\(\s*['"](.+?)["']([,)])/g)) {
Expand Down Expand Up @@ -56,6 +71,9 @@ export default async function transformComponent(code: string, transformer: Supp
ctx.updateUsageMap(sfcPath, [name])
const component = await ctx.findComponent(name, 'component', [sfcPath])
if (component) {
const genComponentUsedPath = ctx.options.genComponentUsedPath
if (genComponentUsedPath.enable)
collectComponentUsedPath(component, sfcPath.replace(process.cwd(), ''), genComponentUsedPath)
const varName = `__unplugin_components_${no}`
s.prepend(`${stringifyComponentImport({ ...component, as: varName }, ctx)};\n`)
no += 1
Expand Down
6 changes: 5 additions & 1 deletion src/core/unplugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { createFilter } from '@rollup/pluginutils'
import chokidar from 'chokidar'
import { createUnplugin } from 'unplugin'
import { Context } from './context'
import { genComponentUsedPath } from './options'
import { shouldTransform, stringifyComponentImport } from './utils'

const PLUGIN_NAME = 'unplugin:webpack'
Expand Down Expand Up @@ -36,7 +37,10 @@ export default createUnplugin<Options>((options = {}) => {
transformInclude(id) {
return filter(id)
},

buildEnd() {
if (options.genComponentUsedPath?.enable)
genComponentUsedPath(options)
},
async transform(code, id) {
if (!shouldTransform(code))
return null
Expand Down
14 changes: 14 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ export type Transformer = (code: string, id: string, path: string, query: Record

export type SupportedTransformer = 'vue3' | 'vue2'

export interface IGenComponentUsedPathOnBuildEndOptions {
/** default: false */
enable?: boolean
exclude?: string | RegExp | (string | RegExp)[] | undefined
/** default: './unplugin-vue-component-used-path.json' */
genFilePath?: string
}

export interface PublicPluginAPI {
/**
* Resolves a component using the configured resolvers.
Expand Down Expand Up @@ -181,6 +189,12 @@ export interface Options {
* Vue version of project. It will detect automatically if not specified.
*/
version?: 2 | 2.7 | 3
/**
* Generate components refrence on buildEnd
* forexample {"ComponentB": ["/src/App.vue", "/src/components/ComponentD.vue" ]}
* @default {enable:false,genFilePath:'./unplugin-vue-component-used-path.json'}
*/
genComponentUsedPath?: IGenComponentUsedPathOnBuildEndOptions
}

export type ResolvedOptions = Omit<
Expand Down

0 comments on commit 8ecf321

Please sign in to comment.