Skip to content

Commit f4570db

Browse files
QuasarmanJohannesStyriaantfu
authoredDec 11, 2024··
feat: allow to scan for custom iconify collections (#318)
Co-authored-by: Johannes Balog <johannes.balog@styria.com> Co-authored-by: Anthony Fu <github@antfu.me>
1 parent 0681df4 commit f4570db

File tree

5 files changed

+39
-20
lines changed

5 files changed

+39
-20
lines changed
 

‎scripts/collections.ts

-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import fs from 'node:fs/promises'
22
import collections from '@iconify/collections/collections.json' with { type: 'json' }
33

44
const names = Object.keys(collections).sort()
5-
const regexPrefix = [...names].sort((a, b) => b.length - a.length).join('|')
65

76
await fs.writeFile(
87
'./src/collection-names.ts',
@@ -12,12 +11,3 @@ await fs.writeFile(
1211
].join('\n'),
1312
'utf-8',
1413
)
15-
16-
await fs.writeFile(
17-
'./src/icon-regex.ts',
18-
[
19-
'// GENERATED BY scripts/collections.ts',
20-
`export const iconMatchRegex = /\\b(?:i-)?(${regexPrefix})[:-]([a-z0-9-]+)\\b/g`,
21-
].join('\n'),
22-
'utf-8',
23-
)

‎src/icon-regex.ts

-2
This file was deleted.

‎src/scan.ts

+32-6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,50 @@
11
import fs from 'node:fs/promises'
22
import type { Nuxt } from 'nuxt/schema'
33
import { glob } from 'tinyglobby'
4-
import { iconMatchRegex } from './icon-regex'
54
import type { ClientBundleScanOptions } from './types'
5+
import { collectionNames } from './collection-names'
66

7-
export function extraIconUsages(code: string, set: Set<string>, ignoreCollections: string[]) {
8-
for (const match of code.matchAll(iconMatchRegex)) {
9-
if (match && !ignoreCollections.includes(match[1])) {
7+
export function extraIconUsages(
8+
code: string,
9+
set: Set<string>,
10+
matchRegex: RegExp,
11+
) {
12+
for (const match of code.matchAll(matchRegex)) {
13+
if (match) {
1014
set.add(`${match[1]}:${match[2]}`)
1115
}
1216
}
1317
}
1418

15-
export async function scanSourceFiles(nuxt: Nuxt, scanOptions: ClientBundleScanOptions | true, set: Set<string> = new Set()) {
19+
export function createMatchRegex(
20+
collections: string[] | Set<string>,
21+
) {
22+
const collectionsRegex = [...collections].sort((a, b) => b.length - a.length).join('|')
23+
return new RegExp('\\b(?:i-)?(' + collectionsRegex + ')[:-]([a-z0-9-]+)\\b', 'g')
24+
}
25+
26+
export async function scanSourceFiles(
27+
nuxt: Nuxt,
28+
scanOptions: ClientBundleScanOptions | true,
29+
set: Set<string> = new Set(),
30+
) {
1631
const {
1732
globInclude = ['**/*.{vue,jsx,tsx,md,mdc,mdx,yml,yaml}'],
1833
globExclude = ['node_modules', 'dist', 'build', 'coverage', 'test', 'tests', '.*'],
1934
ignoreCollections = [],
35+
additionalCollections = [],
2036
} = scanOptions === true ? {} : scanOptions
2137

38+
const collections = new Set([
39+
...collectionNames,
40+
...additionalCollections,
41+
])
42+
for (const collection of ignoreCollections) {
43+
collections.delete(collection)
44+
}
45+
46+
const matchRegex = createMatchRegex(collections)
47+
2248
const files = await glob(
2349
globInclude,
2450
{
@@ -32,7 +58,7 @@ export async function scanSourceFiles(nuxt: Nuxt, scanOptions: ClientBundleScanO
3258
await Promise.all(
3359
files.map(async (file) => {
3460
const code = await fs.readFile(file, 'utf-8').catch(() => '')
35-
extraIconUsages(code, set, ignoreCollections)
61+
extraIconUsages(code, set, matchRegex)
3662
}),
3763
)
3864

‎src/types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ export interface ClientBundleScanOptions {
154154
* Collection names to be ignored when scanning
155155
*/
156156
ignoreCollections?: string[]
157+
/**
158+
* Additional collections that are not or not yet inclduded in the `@iconify` collection
159+
*/
160+
additionalCollections?: string[]
157161
}
158162

159163
export interface ResolvedServerBundleOptions {

‎test/extract.test.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/// <reference types="vite/client" />
22
import { it, expect } from 'vitest'
3-
import { extraIconUsages } from '../src/scan'
3+
import { createMatchRegex, extraIconUsages } from '../src/scan'
4+
import { collectionNames } from '../src/collection-names'
45

56
it('extract icon usages', async () => {
67
const code = await import('../playground/components/ShowcaseFixture.vue?raw').then(m => m.default)
78
const set = new Set<string>()
8-
extraIconUsages(code, set, [])
9+
extraIconUsages(code, set, createMatchRegex(collectionNames))
910

1011
expect(set).toMatchInlineSnapshot(`
1112
Set {

0 commit comments

Comments
 (0)
Please sign in to comment.