Problem
HeyOzwell (and the rest of the AI subtree) is reachable only from the root barrel:
import { HeyOzwell } from '@mieweb/ui';
package.json has an exports map with ./components/*, but there is no entry that
resolves the AI components, so consumers cannot reach them through a subpath.
That makes the AI subtree impossible to code-split in any app that also uses ordinary
@mieweb/ui components. A lazy wrapper like:
const HeyOzwell = lazy(async () => {
const ui = await import('@mieweb/ui');
return { default: ui.HeyOzwell };
});
does not help, because the app already imports the same barrel module statically
(Button, Dropdown, AppHeader, …). Rollup sees one module, so there is no seam to
split on and the whole AI UI is hoisted into the initial chunk.
Impact
Measured in an app (Vite 6 / React 19 / @mieweb/ui@0.7.1) whose only AI usage is a
voice button that is disabled by default:
|
initial chunk |
without the <HeyOzwell> mount |
977 kB |
with the <HeyOzwell> mount |
3,062 kB |
So every user pays ~2.1 MB for a feature that is off. Note this is the AI UI only —
onnxruntime-web (ort.bundle.min, ~463 kB) and hey-buddy already resolve into their
own lazy chunks and behave correctly.
Suggested fix
Add a subpath export for the AI components so they can live in their own chunk, e.g.
and ensure the build emits dist/components/AI/* as a separate entry rather than folding
it into the barrel chunk. Consumers could then write:
const HeyOzwell = lazy(() =>
import('@mieweb/ui/components/AI').then((m) => ({ default: m.HeyOzwell })),
);
Happy to send a PR if that direction looks right.
Version
@mieweb/ui@0.7.1
Problem
HeyOzwell(and the rest of the AI subtree) is reachable only from the root barrel:package.jsonhas anexportsmap with./components/*, but there is no entry thatresolves the AI components, so consumers cannot reach them through a subpath.
That makes the AI subtree impossible to code-split in any app that also uses ordinary
@mieweb/uicomponents. A lazy wrapper like:does not help, because the app already imports the same barrel module statically
(
Button,Dropdown,AppHeader, …). Rollup sees one module, so there is no seam tosplit on and the whole AI UI is hoisted into the initial chunk.
Impact
Measured in an app (Vite 6 / React 19 /
@mieweb/ui@0.7.1) whose only AI usage is avoice button that is disabled by default:
<HeyOzwell>mount<HeyOzwell>mountSo every user pays ~2.1 MB for a feature that is off. Note this is the AI UI only —
onnxruntime-web(ort.bundle.min, ~463 kB) andhey-buddyalready resolve into theirown lazy chunks and behave correctly.
Suggested fix
Add a subpath export for the AI components so they can live in their own chunk, e.g.
{ "exports": { ".": { /* ... */ }, "./components/AI": { "types": "./dist/components/AI/index.d.ts", "import": "./dist/components/AI/index.js" } } }and ensure the build emits
dist/components/AI/*as a separate entry rather than foldingit into the barrel chunk. Consumers could then write:
Happy to send a PR if that direction looks right.
Version
@mieweb/ui@0.7.1