Skip to content

Commit d9eb45c

Browse files
committed
refactor(compat-eslint): drop loadEslintInternals indirection
The wrapper was a cached `require` for one symbol — but Node's `require` is already lazy (loads on first call) and cached (subsequent calls return the same exports). The module-level `eslintInternals` slot, the `loadEslintInternals` function, and the duplicated CodePathAnalyzer constructor type were all re-implementing what `require` already does for free. Inline the require directly inside `runCpaInline` with a `typeof import('...')` annotation that picks up the existing `code-path-analyzer.d.ts`. Same lazy-load behavior, fewer pieces.
1 parent 0585586 commit d9eb45c

1 file changed

Lines changed: 5 additions & 32 deletions

File tree

packages/compat-eslint/index.ts

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,6 @@ import type * as TSSLint from '@tsslint/types';
22
import type * as ESLint from 'eslint';
33
import type * as ts from 'typescript';
44

5-
// `CodePathAnalyzer` is vendored from ESLint's
6-
// `lib/linter/code-path-analysis/` (see `lib/code-path-analysis/`).
7-
// ESLint doesn't expose CPA on any public surface
8-
// (`use-at-your-own-risk` only re-exports lint engines / `builtinRules`),
9-
// so we ship the source ourselves — that drops the last runtime
10-
// `eslint` package dependency. The vendored copy has its
11-
// `eslint/lib/shared/assert` reference replaced with a tiny inline
12-
// `ok()` and the `debug` package replaced with a no-op stub.
13-
// Lazy-loaded so cold lint runs that don't hit a CPA-using rule
14-
// (no-fallthrough / no-unreachable / getter-return / etc.) never
15-
// pay for parsing the ~4500 lines of analyzer source.
16-
let eslintInternals: {
17-
CodePathAnalyzer: new(eventGenerator: {
18-
// ESLint 9.39+ uses `eventGenerator.emit` (function) directly;
19-
// ESLint 9.0-9.38 called `eventGenerator.emitter.emit`. Provide
20-
// both shapes so we work across the supported range.
21-
emit?: (name: string, args: unknown[]) => void;
22-
emitter?: { emit(name: string, ...args: unknown[]): void };
23-
enterNode(node: unknown): void;
24-
leaveNode(node: unknown): void;
25-
}) => { enterNode(node: unknown): void; leaveNode(node: unknown): void };
26-
} | undefined;
27-
function loadEslintInternals() {
28-
if (!eslintInternals) {
29-
eslintInternals = {
30-
CodePathAnalyzer: require('./lib/code-path-analysis/code-path-analyzer.js'),
31-
};
32-
}
33-
return eslintInternals;
34-
}
35-
365
// Build a parse-time-named wrapper around a rule listener. V8's CPU
376
// profile reads the SharedFunctionInfo's parse-time-inferred name, so we
387
// have to compile fresh source per rule with the rule id baked in as a
@@ -596,7 +565,11 @@ function runCpaInline(
596565
enterNode: (target: unknown) => dispatchTarget(target, true, fast, errors, onTarget),
597566
leaveNode: (target: unknown) => dispatchTarget(target, false, fast, errors, onTarget),
598567
};
599-
const { CodePathAnalyzer } = loadEslintInternals();
568+
// CodePathAnalyzer is vendored from ESLint's `lib/linter/code-path-analysis/`
569+
// into our `lib/code-path-analysis/` (ESLint exposes no public surface for
570+
// it). Node `require` is already lazy + cached, so this loads on first
571+
// CPA-mode lint and is reused thereafter — no module-level memo needed.
572+
const CodePathAnalyzer = require('./lib/code-path-analysis/code-path-analyzer.js') as typeof import('./lib/code-path-analysis/code-path-analyzer');
600573
const cpa = new CodePathAnalyzer(wrapped);
601574
tsScanTraverse(file, match, convertContext as any, {
602575
enterNode(target) {

0 commit comments

Comments
 (0)