Skip to content

perf(lint): load Sucrase lazily in validateReactPages - #2547

Merged
os-zhuang merged 1 commit into
mainfrom
fix/lint-lazy-sucrase
Jul 3, 2026
Merged

perf(lint): load Sucrase lazily in validateReactPages#2547
os-zhuang merged 1 commit into
mainfrom
fix/lint-lazy-sucrase

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Summary

@objectstack/lint sits on the kernel boot path, but the react syntax gate (ADR-0081) only runs when a kind:'react' page is actually validated. The top-level import { transform } from 'sucrase' in validate-react-pages.ts made every boot parse ~1.5 MB of transpiler (~16 ms cold require) — the same boot-path problem as the TypeScript compiler in validateReactPageProps, fixed in #2544.

  • Sucrase now loads on the first validated react-source page via the same deferred createRequire pattern (anchor chain import.meta.url__filename → cwd); the public API stays synchronous and unchanged, and sucrase stays a regular dependency in package.json.
  • If the package is missing at call time (image pruning), validation fails with an actionable error instead of killing boot. The loader call sits outside the transpile try so a missing package can't be swallowed as a syntax finding.
  • The boot-path guard test is generalized from lazy-typescript.test.ts to lazy-deps.test.ts, parameterized over LAZY_DEPS = ['typescript', 'sucrase'] at all three levels: structural no-eager-import scan over src, child-process probes of both built dist formats (also asserting per-gate independence — the syntax gate must not load typescript), and in-process lazy-load behavior. An in-worker require.cache probe alone cannot catch a reintroduced eager import: vitest inlines static imports through its transform.

Red-check

Verified the guard goes red for each dep separately by reintroducing the eager imports (string-patched, then reverted):

  • both deps eager → all 4 guard tests fail; the structural scan names both offenders
  • sucrase-only eager → dist probes fail specifically with sucrase was loaded eagerly, at import time

Verification

  • pnpm vitest run in packages/lint: 116/116 green, all 4 guard tests run un-skipped against built dist
  • eslint src clean
  • turbo build --filter=...@objectstack/lint: 61/61 tasks green
  • changeset: patch for @objectstack/lint

🤖 Generated with Claude Code

@objectstack/lint sits on the kernel boot path, but the react syntax
gate (ADR-0081) only runs when a kind:'react' page is actually
validated. The top-level `import { transform } from 'sucrase'` made
every boot parse ~1.5 MB of transpiler (~16 ms cold require) — the same
boot-path problem as the TypeScript compiler in validateReactPageProps,
fixed in #2544.
Sucrase now loads on the first validated react-source page via the same
deferred createRequire (anchor chain import.meta.url → __filename →
cwd); the public API stays synchronous and unchanged, `sucrase` stays a
regular dependency, and a missing package at call time fails validation
with an actionable error instead of killing boot.
The guard test is generalized from lazy-typescript.test.ts to
lazy-deps.test.ts, covering both deps at all three levels (structural
no-eager-import scan over src, child-process probes of both dist
formats, in-process lazy-load behavior) — verified to go red for each
dep separately when its eager import is reintroduced. An in-worker
require.cache probe alone cannot catch it: vitest inlines static
imports through its transform.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jul 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJul 3, 2026 2:13pm

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling size/m labels Jul 3, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 1 changed package(s). ✅

@os-zhuang
os-zhuang merged commit 996c548 into mainJul 3, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the fix/lint-lazy-sucrase branch July 3, 2026 14:16
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@os-zhuang