Fix circular self-imports and add no-self-package-imports lint rule

- Fixes the `Cannot access '_AppRootElementBlueprintesm' before
  initialization` crash in `@backstage/frontend-plugin-api` caused by a
  self-referential import in the packaged ESM.
- Cleans up similar self-imports in `@backstage/catalog-model`,
  `@backstage/core-plugin-api`, `@backstage/plugin-catalog-node`,
  `@backstage/plugin-kubernetes-common`, and
  `@backstage/plugin-kubernetes-node`. Value imports switch to relative
  paths; type-only imports use `import type` so they're erased at
  runtime.
- Adds a new `@backstage/no-self-package-imports` ESLint rule. It reads
  each package's `exports` map, traverses the relative import graph from
  every entry's source file, and only reports imports where the current
  file is in the same bundle as the target entry (same-entry). Files
  that aren't reachable from any entry (tests, scripts, orphans) are
  skipped. `import type`, `package.json` imports, and cross-entry
  self-imports are allowed by default; cross-entry can be opted into
  with `allowCrossEntry: false`.

Signed-off-by: Marat Dyatko <maratd@spotify.com>
Made-with: Cursor
This commit is contained in:
Marat Dyatko
2026-04-23 14:41:33 +02:00
parent 427d5219a6
commit ab1cdbb9db
29 changed files with 810 additions and 25 deletions
+2 -2
View File
@@ -5,10 +5,10 @@
```ts
import { BasicPermission } from '@backstage/plugin-permission-common';
import { Entity } from '@backstage/catalog-model';
import { FetchResponse as FetchResponse_2 } from '@backstage/plugin-kubernetes-common';
import type { FetchResponse as FetchResponse_2 } from '@backstage/plugin-kubernetes-common';
import type { JsonObject } from '@backstage/types';
import type { JsonValue } from '@backstage/types';
import { ObjectsByEntityResponse as ObjectsByEntityResponse_2 } from '@backstage/plugin-kubernetes-common';
import type { ObjectsByEntityResponse as ObjectsByEntityResponse_2 } from '@backstage/plugin-kubernetes-common';
import type { PodStatus } from '@kubernetes/client-node';
import type { V1ConfigMap } from '@kubernetes/client-node';
import type { V1CronJob } from '@kubernetes/client-node';
@@ -15,7 +15,7 @@
*/
import { DetectedError, DetectedErrorsByCluster } from './types';
import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';
import type { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';
import { groupResponses } from '../util';
import { detectErrorsInPods } from './pods';
import { detectErrorsInDeployments } from './deployments';
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { FetchResponse } from '@backstage/plugin-kubernetes-common';
import type { FetchResponse } from '@backstage/plugin-kubernetes-common';
import { GroupedResponses } from '../types';
/** @public */