import { readdirSync, readFileSync, statSync } from 'node:fs' import { join } from 'node:path' import { icons } from '@iconify-json/lucide' import { getIcons } from '@iconify/utils' import type { Plugin } from 'vite' const virtualId = 'virtual:lucide-subset' const resolvedId = `\0${virtualId}` const iconPattern = /i-lucide-([a-z0-9]+(?:-[a-z0-9]+)*)/g const sourceExtensions = /\.(vue|ts|js|mjs)$/ function walk(dir: string, found: Set) { for (const entry of readdirSync(dir)) { const full = join(dir, entry) const stat = statSync(full) if (stat.isDirectory()) { if (entry !== '__tests__') walk(full, found) continue } if (!sourceExtensions.test(entry)) continue for (const match of readFileSync(full, 'utf8').matchAll(iconPattern)) { found.add(match[1]!) } } } export function lucideSubset(roots: string[]): Plugin { return { name: 'lucide-subset', resolveId(id) { return id === virtualId ? resolvedId : null }, load(id) { if (id !== resolvedId) return null const found = new Set() for (const root of roots) walk(root, found) const subset = getIcons(icons, [...found].sort()) return `export default ${JSON.stringify(subset)}` }, } }