Skip to content

tech(core): resolve the bootstrap-icons fallback via fetch - #1642

Open
MrTango wants to merge 5 commits into
masterfrom
pr/icons-fallback-fetch
Open

MrTango wants to merge 5 commits into
masterfrom
pr/icons-fallback-fetch

Conversation

@MrTango

@MrTango MrTango commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

resolveIcon's fallback used a templated import("bootstrap-icons/icons/…"), which webpack turns into a lazy context over all 2078 icons, with its filename→chunk maps in the eager JS. The fallback now fetches a static SVG:

resolveIcon(name)
  @@iconresolver                      # unchanged
  fallback: iconmap.json → fetch
    with data-portal-url → <portal>/++plone++bootstrap-icons/<name>.svg
    without (standalone) → <bundle public path>/bootstrap-icons/<name>.svg

webpack.config.js copies the bootstrap-icons SVGs to dist/bootstrap-icons/ (copy-webpack-plugin), so standalone/CDN integrations and the demo keep working.

Evidence

Production build, master (65a1f85) vs this PR:

master this PR
bundle.min.js 285 KB 225 KB
chunk containing resolveIcon 161 KB 84 KB
JS chunks 3147 1069
dist files 4217 4217 (2078 icon chunks → 2078 static SVGs)

New tests in src/core/utils.test.js (iconresolver fails):

with portal URL    → fetches http://nohost/plone/++plone++bootstrap-icons/house.svg   ✓
without portal URL → fetches <public path>bootstrap-icons/house.svg                    ✓  (before: /++plone++bootstrap-icons/house.svg → "")

markspeciallinks.test.js now stubs fetch with the real icon files (jsdom has no fetch). All 58 suites pass.

Merge Danger

Door: two-way

Blast Radius: small

Only the fallback path changes; Plone resolves icons via @@iconresolver first.

core/utils.js resolved the icon fallback with a templated
import(`bootstrap-icons/icons/${name}`), which webpack turned into a lazy
context over all 2078 icons: ~65KB of filename→chunkid map inside the eager
patterns chunk, ~60KB of the chunk→hash runtime map in bundle.min.js, and
~2000 tiny chunk files in dist — parsed on every page for a fallback that is
almost never hit.

Resolve the fallback by fetching the icon resource URL from iconmap.json
instead (Plone already serves every bootstrap icon as a static resource),
keeping the same return shape (SVG markup string) for callers. Removes the
icon context entirely: the dist chunk count drops from ~3578 to ~1469 files
and bundle.min.js shrinks by ~80KB.
… of Plone

Without a portal URL the fallback requested /++plone++bootstrap-icons/...,
which only Plone serves, so standalone and CDN integrations got empty icons.
Copy the bootstrap-icons SVGs next to the bundle and fetch them from
webpack's public path in that case.

The markspeciallinks tests failed because jsdom has no fetch; they now stub
it to serve the icon files.
@MrTango
MrTango marked this pull request as ready for review October 8, 2026 14:17
@MrTango
MrTango requested a review from thet October 8, 2026 14:17

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant