42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
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<string>) {
|
|
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<string>()
|
|
for (const root of roots) walk(root, found)
|
|
const subset = getIcons(icons, [...found].sort())
|
|
return `export default ${JSON.stringify(subset)}`
|
|
},
|
|
}
|
|
}
|