refactor(web): migrate icons to unplugin-icons - #1467
Conversation
Replace the hand-written gen-icon-data.mjs + @iconify/utils runtime rendering with unplugin-icons build-time imports. The public API (<Icon name>, iconSvg, IconName, SIZE_PX, NAME_TO_REMIX) is unchanged; 127+ call sites are untouched. - add unplugin-icons@^23.0.0 (devDep) + Vite Icons() plugin (compiler: vue3) - rewrite src/lib/icons.ts: static ~icons/ri/* imports (component + ?raw) for 56 distinct Remix icons across 59 IconName entries - Icon.vue renders <component :is> with unknown-name fallback - append ICON_GROUPS export for DesignSystemView catalog - DesignSystemView: v-for catalog, remove legacy-script references - delete gen-icon-data.mjs, gen-icon-catalog.mjs, icon-data.ts, gen:icons script - remove @iconify/vue and @iconify/utils from dependencies; move @iconify-json/ri to devDependencies - drop Icon.vue from check-style ICON_EXEMPT (no hand-written <svg>)
NAME_TO_REMIX was a Record<IconName, string> table introduced to map internal icon names to their ri: ids. After the unplugin-icons migration it has no production consumers — only icons.test.ts imported it (for two drift tests) and DesignSystemView mentioned it in descriptive copy. The ICONS table already conveys the same ri: id via each entry's paired component + ?raw imports (e.g. RiFolderOpenLine / RawFolderOpenLine). - remove NAME_TO_REMIX const from src/lib/icons.ts (-63 lines) - remove NAME_TO_REMIX import + describe block from icons.test.ts - update DesignSystemView §02 copy: describe the import-pair idiom and stop claiming ICON_GROUPS is sourced from NAME_TO_REMIX
🦋 Changeset detectedLatest commit: 5f3ab12 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
❌ Nix build failed Hash mismatch in
Please update |
commit: |
Adding unplugin-icons changed pnpm-lock.yaml, so the fixed-output pnpmDeps derivation hash is stale. Update to the hash reported by the Nix Build CI run.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b35fe65e43
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4ff2f8ef03
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Related Issue
No linked issue. This addresses an internal simplification of
apps/kimi-web's icon infrastructure.Problem
apps/kimi-webmaintained a hand-written icon-cropping script (scripts/gen-icon-data.mjs+scripts/gen-icon-catalog.mjs) that pre-extracted Remix Icon SVG bodies intosrc/lib/icon-data.ts, then used@iconify/utils'iconToSVGto render them at runtime. This added friction — every icon change required manually regenerating and committing a generated file — duplicated the name mapping across two scripts, and pulled@iconify/utilsinto the runtime bundle even though it was only needed at build time.@iconify/vuewas also a declared dependency but never imported.What changed
unplugin-icons(Vite plugin,compiler: 'vue3'). Only icons statically imported insrc/lib/icons.tsend up in the production bundle, fully offline and tree-shaken at build time.src/lib/icons.ts: each of 56 distinct Remix icons is imported as both a Vue component (~icons/ri/<name>) and a raw SVG string (~icons/ri/<name>?raw), backed by aRecord<IconName, IconEntry>table for 59 internal names. The public API (<Icon name>,iconSvg(name, size),IconName,SIZE_PX,IconEntry) is unchanged, so the 127+ call sites need no edits.Icon.vuenow renders<component :is>with an unknown-name fallback, instead ofv-htmlinto a hand-written<svg>.DesignSystemView§02 catalog is rendered viav-forover a newICON_GROUPSexport; the §02 copy no longer references the deleted scripts.scripts/gen-icon-data.mjs,scripts/gen-icon-catalog.mjs,src/lib/icon-data.ts, thegen:iconsnpm script, and theNAME_TO_REMIXconstant (dead code).@iconify/vueand@iconify/utilsfromdependencies; moved@iconify-json/ritodevDependencies(unplugin-icons needs it at build time).@iconify/utilssurvives only as a transitive dependency ofmermaidandunplugin-icons.declare module '~icons/*?raw'ambient type shim insrc/env.d.tsso?rawimports type asstring(unplugin-icons' Vue types declare~icons/*asFunctionalComponent, which would otherwise conflict).scripts/check-style.mjsICON_EXEMPT(removedIcon.vuesince it no longer hand-writes an<svg>) and the.kw-iconcomment insrc/style.css.All four quality gates pass:
typecheck,vitest(339 tests),check:style, andbuild.Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.