Skip to content

feat: add no-module-level-new lint rule#51

Merged
danielchen0 merged 8 commits intomainfrom
danielchen0/no-module-level-new
May 4, 2026
Merged

feat: add no-module-level-new lint rule#51
danielchen0 merged 8 commits intomainfrom
danielchen0/no-module-level-new

Conversation

@danielchen0
Copy link
Copy Markdown
Collaborator

Summary

  • Adds a new no-module-level-new lint rule that detects new Expression() calls at module scope, which execute during SSR and may crash or cause side effects
  • Allows safe constructors (Error, URL, Map, Set, RegExp, Date, TextEncoder, etc.) while flagging SSR-unsafe ones like QueryClient, IntersectionObserver, WebSocket
  • Tagged as web platform rule

Motivated by a design agent failure where const queryClient = new QueryClient() at module level in layout.jsx compiled fine but crashed at SSR runtime, causing blank screenshots and an ~8 minute debugging loop.

Manual QA Plan

Scenario Action Expected
Module-level unsafe new Lint const qc = new QueryClient() at top level Error reported
Safe constructor Lint const m = new Map() at top level No error
Inside function Lint function f() { new QueryClient() } No error
Inside useEffect Lint useEffect(() => { new QueryClient() }) No error
Full suite npm test All 416 tests pass

Detects `new Expression()` calls at module scope that execute during SSR
and may crash or cause side effects. Allows safe constructors (Error, URL,
Map, Set, RegExp, Date, etc.) while flagging SSR-unsafe ones like
QueryClient, IntersectionObserver, WebSocket, etc.

Motivated by a design agent failure where `const queryClient = new QueryClient()`
at module level compiled fine but crashed at SSR runtime.
danielchen0 and others added 2 commits March 3, 2026 19:49
Auto-fix prettier formatting in src/rules/no-module-level-new.ts
@daniel-chen-1
Copy link
Copy Markdown

daniel-chen-1 Bot commented Apr 28, 2026

Pushed an auto-fix commit to unblock the failing Lint & Format check (Prettier formatting in src/rules/no-module-level-new.ts). CI should re-run shortly.

Copy link
Copy Markdown
Contributor

@lainterr lainterr Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed as steward. Looks solid — approving.

Logic is correct: walks the parent chain to confirm new is at module scope (not nested in a function/class/method). The SAFE_CONSTRUCTORS allowlist is sensible and matches the intent (cheap, side-effect-free).

Two minor suggestions, non-blocking:

  1. Consider adding Symbol, Object, Array, String, Number, Boolean to SAFE_CONSTRUCTORS — all are pure builtins. (Some are unusual with new, but if the agent writes them they're harmless.)

  2. Browser-fetch-style classes (Headers, Request, Response, URL, URLSearchParams, FormData, Blob, AbortController, EventTarget) are also typically safe at module scope. URL/URLSearchParams are already covered. Could add the rest to reduce false positives in API-route adjacent code.

Neither blocks shipping. The current allowlist already covers the noisiest cases.

lainterr Bot and others added 5 commits May 1, 2026 01:15
Auto-resolved trivial conflicts in shared files (README.md,
src/rules/index.ts, src/rules/meta.ts, tests/config-modes.test.ts)
by applying the PR's net additions on top of current main and
bumping the rule count.

Resolved by Lainter (steward).
Auto-resolved trivial conflicts in shared files. Resolved by Lainter (steward).
Rebase pulled in unformatted README.md changes; this restores prettier formatting.
@daniel-chen-1
Copy link
Copy Markdown

daniel-chen-1 Bot commented May 3, 2026

Auto-fix: Lint & Format CI was failing on this rebase because README.md needed prettier formatting. Pushed prettier --write README.md as a follow-up commit. CI should go green on the next run.

@danielchen0 danielchen0 merged commit 239f0cc into main May 4, 2026
7 checks passed
daniel-chen-1 Bot pushed a commit that referenced this pull request May 4, 2026
Rebased onto main to resolve conflicts after #51 merge.
daniel-chen-1 Bot pushed a commit that referenced this pull request May 4, 2026
Rebased onto main to resolve conflicts after #51 merge.
daniel-chen-1 Bot pushed a commit that referenced this pull request May 4, 2026
Rebased onto main to resolve conflicts after #51 merge.
daniel-chen-1 Bot pushed a commit that referenced this pull request May 4, 2026
…ules

Rebased onto main to resolve conflicts after #51 merge.
danielchen0 added a commit that referenced this pull request May 4, 2026
Rebased onto main to resolve conflicts after #51 merge.
danielchen0 added a commit that referenced this pull request May 4, 2026
Rebased onto main to resolve conflicts after #51 merge.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants