Uh oh!
There was an error while loading. Please reload this page.
chore(console): pin the 43 ineffective dynamic imports to a checked ledger - #6007
Merged
yinlianghui merged 1 commit intoAug 24, 2026
Merged
Conversation
…edger Every console `vite build` emitted 43 `INEFFECTIVE_DYNAMIC_IMPORT` warnings, all from `packages/fields`: each `import()` in the widget-loader map is defeated by a static edge to the same module, so the laziness is decoration. The warnings are true and unactionable, and 43 of them scrolling past every build is how a build log stops being read. They are promoted, not suppressed. `scripts/vite-ineffective-dynamic-imports.ts` holds the ledger of defeated modules and a Vite plugin that: - replaces the pinned 43 with one summary line (27 via `FieldEditWidget.tsx`, the inline cell editor; 16 via the `@object-ui/fields` barrel), computed from the live build rather than pinned; - fails the build on an UNPINNED ineffective dynamic import, printing rolldown's own warning text for it first; - fails the build on a pinned entry that did NOT fire. That is the counter-probe: a console build that dies before chunk assignment reports zero of these warnings, which reads exactly like "fixed". The module graph is untouched. Removing the defeating static edges is a breaking change to `@object-ui/fields` (16 `MISSING_EXPORT` errors, 14 widget classes imported by name across four packages) and buys zero bytes, because the `ui-components` `advancedChunks` group claims `packages/fields/**` and overrides async-only reachability a second time. Control: `MarkdownContent.tsx` has an undefeated `React.lazy`, no static importer, emits no warning, and still lands in the eager `ui-components-*.js`; counter-probed against `plugin-map`, `plugin-charts` and `plugin-report`, which the same walk reports as lazy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSoz9uGhaaSgiq3hshtN7L
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 24, 2026 12:42
Uh oh!
There was an error while loading. Please reload this page.
yinlianghui
deleted the
claude/issue-5325-fields-ineffective-dynamic-imports
branch
August 24, 2026 12:53
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 freeto 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.
Fixes#5325
Measured first, then chose — the card's own instruction. Both endings were on the table; the measurement picked this one, and it matches the maintainer ruling already recorded on the card (2026-08-22, option C).
What the build actually emits, measured on
8d3a5294a43, not "13+". All 43 come from
packages/fields; the threeapps/console/src/pages/*warnings a previous round measured (DocPage,DocsLayout,DocsSlug) are gone. Two mechanisms, and the card was right that the shape is not uniform:import()packages/fields/src/FieldEditWidget.tsx(+ the barrel) — the grid's inline cell editor, which imports synchronously because a cell edits in placepackages/fields/src/index.tsxalone — the barrel's ownexport * from './widgets/*.js'Is the lazy path reachable? Yes — and it still cannot pay off
getLazyFieldWidgetis public API with two live production consumers (app-shell/src/views/ActionParamDialog.tsxandplugin-grid/src/components/BulkActionDialog.tsx), so deleting theimport()calls is off the table.But the laziness is defeated a second time, one level up, by chunking — #5266's own mechanism.
apps/console/vite.config.tsdeclares anadvancedChunksgroupui-componentswhose test matchespackages/(components|fields); group assignment overrides a module's async-only reachability, and that chunk is eager becausepackages/componentsis reached synchronously from the entry.Control, re-measured on this branch:
packages/fields/src/widgets/MarkdownContent.tsxhas a workingReact.lazy(fromwidgets/richTextDisplay.tsx), is re-exported by nothing, and has no static importer anywhere in production code — so it emits no warning at all and is absent from the ledger. It still lands in the eagerui-components-CNyoWt-3.js. Counter-probe soEAGERis not a stuck answer: the same walk reportslazyforplugin-map,plugin-chartsandplugin-report.So barrel surgery moves zero bytes — and it is a breaking change besides: 16
MISSING_EXPORTerrors, 14 widget classes imported by name acrossplugin-detail,plugin-form,app-shellandapps/console, plus published consumers. That is exactly what the maintainer ruled out.What this PR does — promotes the warnings, does not silence them
A one-line
if (code === 'INEFFECTIVE_DYNAMIC_IMPORT') return falsewould satisfy "stop the noise" and be strictly worse than the noise: those 43 lines are currently the only thing in the repo saying the laziness does not work, and a 44th widget joining tomorrow would land in silence.scripts/vite-ineffective-dynamic-imports.tsholds the ledger of the 43 defeated modules plus a Vite plugin that:MISSING_EXPORTerrors reported0, which reads identically to "fixed".The module graph is untouched. Option A (stop
ui-componentsclaimingpackages/fields/**, then remove the static edges) stays on hold as the ruling left it; the ledger header records why, and this PR does not foreclose it — when someone does that work, the ledger shrinks and the build says so.Verification, all on
6774f83ddConsole
vite build:BUILD_EXIT=0, rawINEFFECTIVE_DYNAMIC_IMPORTlines in the log0, and one summary line in their place:Eager closure byte-identical before and after —
3,310,419gzipped,52/508chunks — as a graph-neutral change must be.Reverse verification of the gate, four legs. Three through a minimal rolldown build driving the real plugin, one through the real console build:
pinned: [])+ .../widget.jsnamed- packages/fields/src/widgets/GhostField.tsxnamed, with the "distrust is the zero" wordingVectorField.tsxline (mutation confirmed on disk:grep -c1 to 0,git diff --stat1 deletion)BUILD_EXIT=1, rolldown's rawVectorField.tsxwarning printed,+ packages/fields/src/widgets/VectorField.tsxnamedThe ablation restore leg was re-run to green on
6774f83dd(the readings above are from that restored build), andgit statusis clean.Gates:
pnpm --filter @object-ui/console type-checkexit 0 (which compilesvite.config.tsandscripts/vite-*.ts),pnpm type-check:scriptsexit 0,pnpm check:control-bytes/lint:coverage/type-check:coverageall OK, andpnpm exec vitest runoverscripts/__tests__/forscripts-type-check,vitest-invocation-guard,check-eager-closure-budgetand the newvite-ineffective-dynamic-imports— 4 files, 86 tests passed. ESLint on the three changed files: 3 files linted, 0 errors, 0 warnings (narrowed;eslint.config.jsenables no type-aware linting — noproject/projectService— so this diff cannot move the verdict on any untouched file).Note for review: the fix is outside the dispatched fence, necessarily
The dispatch fenced this to
packages/fields/**. Nothing inside that fence can fix it:packages/fields' own build emits zero of these warnings (measured — the whole 34-package dependency build emits none); they exist only in the consumer's bundle, so the only lever is the consumer's build config. The one file changed outsidepackages/fieldsisapps/console/vite.config.ts, which already houses the two sibling guards of exactly this genre (assertLazyLinterStaysLazy,emitEagerClosureReport). Disjoint from every concurrent sibling claim (packages/types,packages/components,packages/plugin-view); the two new files underscripts/are new files, not edits.The dispatch also carried a standing "do not fix this by suppressing the warning", which the maintainer's own option-C ruling ("stop them reading as noise") has to be reconciled with. The reconciliation is the design above: the signal is not removed, it is made into a gate.
Generated by Claude Code