perf(react-icons): reuse canonical fonts instead of regenerating#1105
Merged
Conversation
9e4c6d3 to
439bd37
Compare
📋 PR Validation SummaryCheck the Build react library job summary for detailed reports:
|
68cc82f to
2103cf3
Compare
dmytrokirpa
approved these changes
Jun 29, 2026
react-icons previously re-ran fantasticon 4x (~48s/variant) to build font families that already exist in the repo-root fonts/ source of truth. Replace that with a copy step. - importer/generateFont.js: make font output byte-deterministic (ttf.ts=0 pins svg2ttf timestamps; sort glob for stable codepoints) - importer/package.json: seed Light/Resizable codepoints from root fonts/ so they stay stable across releases (previously unseeded -> drifted) - react-icons: replace generate:font-* (fantasticon) with copy-base-fonts.js that copies binaries + glyph-named JSON from root fonts/; drop unused concurrently dep - nx: add cacheable deploy:fonts target (importer/project.json) keyed on assets/ via new "fonts" namedInput; react-icons build invalidates on root fonts/ changes - rename nx project @fluentui/system-icons-processing -> system-icons-processing
Deduplicate input cache configuration shared across the font/svg generation targets. - nx.json: replace the monolithic "fonts" namedInput with composable "assets", "iconGenerationToolchain", "fontGenerationToolchain" (composes the former), and "fontArtifacts" - importer (deploy:fonts): inputs -> ["assets", "fontGenerationToolchain"] - svg-icons (build): reuse ["assets", "iconGenerationToolchain"] instead of inlining assets/** + importer scripts; also fix dangling implicitDependency @fluentui/system-icons-processing -> system-icons-processing - react-icons (build): replace the 4 inlined fonts/* globs with "fontArtifacts"
8bad1a5 to
5c00fac
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
react-iconsbuild re-ranfantasticon4× (~48s/variant) to generate font families that already exist in the repo-rootfonts/folder — the single source of truth, regenerated at release time byimporter'sdeploy:fonts. This PR removes that redundant work: react-icons now just copies the canonical fonts.Changes
1. Deterministic font generation —
importer/generateFont.jsformatOptions.ttf.ts = 0pins svg2ttf's created/modified timestamps so font binaries are byte-deterministic across builds (WOFF/WOFF2 wrap the TTF bytes). This was the root cause of font binary churn between builds.readdirorder.2. Stable cross-release codepoints —
importer/package.jsonfonts/JSON. Previously they were unseeded and could drift on every build; now all four families are seeded.3. react-icons copies instead of regenerating
scripts/copy-base-fonts.jscopies the font binaries + glyph-named codepoint JSON from rootfonts/(skips the unused.css/.htmlfantasticon byproducts).generate:fontis now that single copy step — the fourgenerateFont.js(fantasticon) invocations are removed from the react-icons build.concurrentlydevDependency.4. nx caching
deploy:fontstarget (importer/project.json) keyed onassets/**+ the generation scripts, output{workspaceRoot}/fonts.buildcache inputs now include the rootfonts/artifacts, so it invalidates when fonts change.@fluentui/system-icons-processing→system-icons-processing(npm package name unchanged).5. DRY cache inputs via composable named inputs
namedInputsinnx.json, each defined once:assets—assets/**iconGenerationToolchain— sharedimporter/generate.js,replace-in-files.js,svgo.config.shared.cjsfontGenerationToolchain— composesiconGenerationToolchain+generateFont.js,svgo.config.mjs,package.jsonfontArtifacts—fonts/FluentSystemIcons-*.{ttf,woff,woff2,json}importer(deploy:fonts),svg-icons(build), andreact-icons(build) now reference these instead of inlining the same globs.implicitDependencyinsvg-icons(@fluentui/system-icons-processing→system-icons-processing) surfaced by the rename.Behavior note (Option A: pure copy)
Brand-new icons added between releases won't have font glyphs in react-icons until a release runs
deploy:fonts(which precedes the react build inpublish.yml). Published output stays correct.Verification
react-icons:build✅ (no fantasticon runs)build-verify127 tests ✅,convert-font.utils8 tests ✅ — no snapshot changes neededlib/utils/fonts/*is now byte-identical to rootfonts/(expected one-time shift from raw → optimized geometry; functionally identical glyphs/codepoints)generateFont.jsruns now produce byte-identical ttf/woff/woff2svg-icons:buildproduces a cache hit on re-runFollow-up (not in this PR)
Regenerating the committed root
fonts/with the new deterministic bytes (deploy:fonts) is left as a separate, reviewable commit.