2.5 KiB
Stage 17: Frontend Page Modules and Shared Components
Scope
This stage establishes frontend feature ownership without changing page markup, API contracts, permissions, visual design, or user interaction. The build-free deployment model is retained.
Page Module Runtime
static/pages/runtime.js owns the page lifecycle registry. Each feature registers its views in
static/pages/<feature>/page.js and declares named enter and leave actions. The application
injects the existing feature functions into that runtime, so page modules do not reach into
another feature's state or DOM.
The lifecycle boundary now owns:
- page-specific data loading after a successful shell mount;
- member-aware entry for Screener, Mentor, and Wentian;
- auction timer cleanup when leaving Auction;
- canvas, dust, and performance cleanup when leaving Wentian;
- the internal Screener Tracking view's ownership relationship.
openView is now a generic coordinator. It validates the route, asks the page runtime to leave
the previous page, mounts through the shared shell, and enters the next page. It contains no
page-name branch chain.
Shared Components
static/shared/components.js is the common rendering boundary for small, stable DOM patterns.
The first migrated component is the empty state used across market rotation, themes,
Dragon-Tiger, review, Screener, Wentian history, alerts, entity details, and administration.
It centralizes escaping and class composition while preserving the exact existing markup.
Collection rendering and text assignment are exposed for later incremental migrations. They
remain dependency-free and use XiaobaiUI for safe escaping.
Enforcement
Frontend boundary tests verify that:
- shared components load after UI primitives and before page code;
- the page runtime loads before every feature registration and before
app.js; - every public and internal workspace belongs to exactly one feature page module;
openViewcontains no feature-specific view comparisons;- shared empty-state rendering is used by multiple feature families;
- provider requests still exit only through
shared/api.js.
Compatibility and Residual Risk
Feature renderers and event handlers still reside in app.js; moving them all at once would
create a high-risk rewrite across already accepted workflows. The new lifecycle and component
boundaries let those functions move feature by feature later without changing navigation or
loading behavior. Dedicated mobile composition remains the next governance phase.