Skip to content

🪩 feat: Compact Long Runtime Imports Into Namespaces - #16622

Open
lia-by-librechat[bot] wants to merge 8 commits into
devfrom
lia/compact-value-imports
Open

lia-by-librechat[bot] wants to merge 8 commits into
devfrom
lia/compact-value-imports

Conversation

@lia-by-librechat

@lia-by-librechat lia-by-librechat Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Depends on #16576. This is a separate follow-up for runtime imports; the type-import PR and its branch are unchanged. Both PRs target dev. Until #16576 lands, this branch includes its cleanup implementation, so the base-to-head diff also contains the prerequisite. The runtime-only delta is the changes after c32c248102074b54633ccebec7fe061e3a572a89.

Long named runtime imports take the same vertical space as type imports. Normal scoped cleanup now compacts eligible value imports into import * as m, alongside the existing import type * as t conversion. The existing pre-commit sorter fixes candidates, and normal --check and changed-file CI enforce them without a flag. References, aliases, JSX tags and object shorthand are updated together. No application source is bulk-migrated.

npm run sort-imports -- path/to/file.tsx
npm run sort-imports:check -- path/to/file.tsx

How it works

The converter uses the current file's TypeScript symbols, not regex reference replacement or a project-wide compiler load. Named value imports exceeding .prettierrc's printWidth become collision-free runtime namespaces. Type-only imports keep separate type namespaces. JavaScript/JSX and Windows paths are supported too. Imports backing explicit @jsx/@jsxFrag factories or an implicit classic React factory stay named because JSX emission references those bindings outside the ordinary identifier tree.

-import { Button, Panel, PanelHeader, PanelContent, PanelFooter } from './primitives';
+import * as m from './primitives';

-const props = { Button };
-const view = <Panel><Button /></Panel>;
+const props = { Button: m.Button };
+const view = <m.Panel><m.Button /></m.Panel>;

Imports containing direct function calls or template tags stay named. A namespace call can change this, and wrapping it to avoid a receiver breaks TypeScript's assertion-function narrowing and never-return control flow. This converter intentionally does not resolve imported signatures, so it cannot prove those rewrites safe. The exclusion applies through optional calls, parentheses, generic instantiations, non-null assertions and type assertions. It also preserves React hook lint coverage. Independent eligible imports in the same file still compact.

Existing member calls such as service.read() keep their receiver. Namespace property reads retain live ESM bindings, and object shorthand expands without changing its key. __proto__ shorthand uses a computed key to preserve an own data property instead of invoking object-literal prototype-setter semantics, including when the identifier is escaped. Callback values and constructors can still be qualified without rewriting their invocation targets. Direct eval, assignment targets, default/mixed imports, commented clauses, re-exports, conflicting symbols, and unsupported references also stay unchanged. Side-effect imports remain sorter barriers. Cleanup first establishes the existing sorter's normal order, then verifies that shortened clauses do not change value-import order. If they would, runtime compaction is skipped for that file while type compaction still applies. This prevents an additional module-initialization reorder caused by shortening, without changing the existing sorting policy.

Type of change

  • Feature
  • Tests / tooling / CI

Testing

Tested environments/configuration: Node.js 24.16.0, TypeScript 5.9.3, Prettier 3.6.2, and locked Rolldown 1.2.6 for a local bundle smoke fixture.

Automated tests:

  • node --test scripts/imports/compact.test.mts: all 37 focused tests passed, covering prior type safety plus executed ESM before/after fixtures for direct-call/tag exclusions, generic wrappers, live bindings, receivers, constructors, shorthand/prototype keys and JSX; compiler fixtures also verify assertion and never-return narrowing before/after cleanup, including qualified member assertions; JavaScript/Windows paths; hook/direct-eval/write exclusions; required hook and Static Checks enforcement; executed module-initialization order and explicit/qualified JSX factory pragmas; safe runtime ordering and idempotence.
  • npx --no-install tsc --noEmit --project scripts/imports/tsconfig.json: passed.
  • Touched-file ESLint and Prettier checks, plus package-manifest validation via Static Checks: passed.
  • Read-only CLI source smoke checked all 5,067 tracked source files through the complete cleanup pipeline, including the order-safety fallback, and confirmed no source contents changed. It intentionally reported 458 files needing cleanup with exit code 1; this is existing whole-tree cleanup debt, not a clean-tree claim or bulk migration.
  • Local locked-bundler smoke verifies runtime parity and removal of an unused large export when named imports become static namespace references. The fixture passed: 202 bytes before and 201 after, with identical [42,true] output and the unused large export removed. This is a bounded fixture, not a whole-application bundle-size claim.

Full application tests, workspace builds/typechecks, Lighthouse, circular-dependency detection, and upstream design-rule build/suppression gates are not run locally because the isolated installation contains tooling dependencies only. Applicable CI checks run on the published head.

Screenshots / recordings

No user-facing change.

Risk / compatibility

This changes required import style on processed files but does not replace functions, snapshot live bindings, or make namespace access dynamic. Unsupported patterns are conservatively skipped. Directly invoked imports remain named to preserve both this semantics and TypeScript control-flow effects. Hook calls remain recognizable to hook lint. Namespace tree-shaking depends on the bundler and static access; a focused Rolldown fixture is checked locally. Changed-file enforcement avoids an unrelated full-tree migration.

Checklist

Verification status

Published head: 370accdd39fdb2c4fecb3f2bd9e8a05eea655584. All 37 focused tests, tooling no-emit compilation, touched-file lint/formatting, package-manifest validation, locked Rolldown smoke and read-only CLI validation passed locally with the stated whole-tree cleanup debt. Fresh independent review and exact-head CI are running. The finding ledger retains fixes for V1 (P2, generic call receivers), V2 (P2, prototype shorthand), V3 (P2, assertion/never-return analysis), V4 (P2, value-import evaluation order), and V5 (P2, implicit JSX factories). No findings are rejected or open. Earlier-head review and CI results do not cover this revision.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Review head d30afb1: separate follow-up to #16576, adding required safe runtime-import namespace cleanup and JSX/shorthand reference updates. Bare calls and tags retain their original receiver semantics; live bindings remain live. Direct hooks, eval, writes, mixed/default imports, comments and re-exports are excluded. All 25 focused tests, tooling no-emit compilation, touched-file lint/formatting and package-manifest validation passed locally. Locked Rolldown smoke retained runtime parity and removed an unused export (181 bytes before, 180 after in the fixture). The dependency branch remains c32c248. Title verification: 🪩 has 1 prior occurrence (1 subject-leading, an unrelated shimmer frame) in 5,750 indexed commits through 2026-09-30 22:35:22 UTC; sentinel passed.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Review head 7308240: fixes both supported P2 findings from the previous runtime head. Generic-instantiation calls and tags retain unbound receiver semantics with valid TypeScript emission; proto shorthand stays an own data property, including escaped spellings. All 27 focused tests, tooling no-emit compilation, touched-file lint/formatting, manifest validation and the locked-bundler smoke passed. Earlier-head review and CI do not cover this revision. Finding ledger: V1 (P2, generic-instantiation call receivers), fixed in this head; V2 (P2, prototype-sensitive shorthand), fixed in this head. No rejected findings. Dependency #16576 remains unchanged at c32c248.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Review head b2f58de: invariant-based control-flow fix after the second actionable review. Imports containing direct calls or template tags now stay named because the local-only binder cannot resolve assertion/never-return signatures; cleanup no longer emits comma-expression callees. Safe value reads, JSX, callback values, constructors and existing member receivers still compact. All 32 focused tests, tooling no-emit compilation, lint, formatting and manifest validation passed. V3 (P2, assertion/never-call analysis) fixed in this head; V1 generic calls now remain named and V2 prototype shorthand stays computed. No rejected findings. The prior head API shard 4 failure was a timeout in unchanged subagentThreads.spec.ts (refreshes retained cancellation result flags after durable collection); no code in that subsystem is modified. Exact-head CI and fresh independent review are required.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Review head 370accd: fixes V4 (P2, shortening can reorder runtime module initialization) and V5 (P2, implicit JSX factory/fragment bindings). Cleanup keeps the existing sorter’s normal value order; if shortened clauses would reorder it, runtime compaction falls back to type-only cleanup for that file. Explicit @jsx/@jsxFrag bindings and implicit classic React factories remain named. All 37 focused tests, tooling no-emit compilation, lint/formatting, manifest validation and locked Rolldown smoke passed locally. Executed regressions cover initialization snapshots and JSX pragma emission; read-only whole-source check preserved all 5,067 tracked source files. Existing V1/V2/V3 safeguards are retained. No rejected findings. Dependency #16576 remains unchanged at c32c248. Earlier-head reviews and CI do not cover this revision.

@codegraph-librechat codegraph-librechat Bot added 🗺️ Build Tooling codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) 🗺️ Monorepo Tooling codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) labels Oct 1, 2026
@codegraph-librechat codegraph-librechat Bot added the 🗺️ Build & Test Tools codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) label Oct 15, 2026

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

🗺️ Build & Test Tools codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) 🗺️ Build Tooling codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) 🗺️ Monorepo Tooling codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant