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

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 3, 2026 2:13pm

Request Review

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

github-actions Bot commented Jul 3, 2026

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 main Jul 3, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the fix/lint-lazy-sucrase branch July 3, 2026 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant