Skip to content

Commit 23f7855

Browse files
emilyinurearendjrautofix-ci[bot]ematipico
authored
fix(noImportCycles): prevent flagging on single file import cycling (#6765)
Co-authored-by: Arend van Beelen jr. <[email protected]> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Emanuele Stoppa <[email protected]>
1 parent 8e97b89 commit 23f7855

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

.changeset/icy-results-wonder.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
Fixed [#6569](https://github.com/biomejs/biome/issues/6569): Allow files to export from themselves with `noImportCycles`.
6+
7+
This means the following is now allowed:
8+
9+
```js
10+
// example.js
11+
export function example() {
12+
return 1;
13+
}
14+
15+
// Re-exports all named exports from the current module under a single namespace
16+
// and then imports the namespace from the current module.
17+
// Allows for encapsulating functions/variables into a namespace instead
18+
// of using a static class.
19+
export * as Example from './example.js';
20+
21+
import { Example } from './example.js';
22+
```
23+
```

crates/biome_js_analyze/src/lint/nursery/no_import_cycles.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ declare_lint_rule! {
2525
/// only go in a single direction, i.e. they don't point "back" to the
2626
/// importing file.
2727
///
28+
/// However, files that import themselves are allowed, and the rule won't trigger for these use cases.
29+
/// This allows for encapsulation of functions/variables into a namespace instead of using a
30+
/// static class (triggers [noStaticOnlyClass](https://biomejs.dev/linter/rules/no-static-only-class)).
31+
///
2832
/// :::note
2933
/// This rule is computationally expensive. If you are particularly
3034
/// pressed for lint time, or don't think you have an issue with dependency
@@ -79,6 +83,16 @@ declare_lint_rule! {
7983
/// }
8084
/// ```
8185
///
86+
/// ```js,file=foobaz.js
87+
/// export function foo() {
88+
/// console.log("foobaz");
89+
/// }
90+
///
91+
/// export * as baz from './foobaz.js';
92+
///
93+
/// import { baz } from './foobaz.js';
94+
/// ```
95+
///
8296
/// ```ts,file=types.ts
8397
/// import type { bar } from "./qux.ts";
8498
///
@@ -243,6 +257,12 @@ fn find_cycle(
243257
}
244258

245259
if path == ctx.file_path() {
260+
// https://github.com/biomejs/biome/issues/6569
261+
// prevent flagging on import cycles when they are isolated to a single file
262+
if stack.is_empty() && start_path == path {
263+
continue;
264+
}
265+
246266
// Return all the paths from `start_path` to `resolved_path`:
247267
let paths = Some(start_path.to_string())
248268
.into_iter()
@@ -254,6 +274,7 @@ fn find_cycle(
254274
)
255275
.chain(Some(path.to_string()))
256276
.collect();
277+
257278
return Some(paths);
258279
}
259280

crates/biome_js_analyze/tests/specs/nursery/noImportCycles/valid.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,13 @@
33
import { foo } from "./invalidFoobar";
44

55
foo();
6+
7+
export function bar() {
8+
return 1;
9+
}
10+
11+
export * as bar from "./valid"
12+
13+
import { foobar } from "./valid"
14+
15+
foobar.bar();

crates/biome_js_analyze/tests/specs/nursery/noImportCycles/valid.js.snap

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,14 @@ import { foo } from "./invalidFoobar";
1010
1111
foo();
1212
13+
export function bar() {
14+
return 1;
15+
}
16+
17+
export * as bar from "./valid"
18+
19+
import { foobar } from "./valid"
20+
21+
foobar.bar();
22+
1323
```

0 commit comments

Comments
 (0)