Environment information
CLI:
Version: 2.1.4
Color support: true
Platform:
CPU Architecture: x86_64
OS: macos
Environment:
BIOME_LOG_PATH: unset
BIOME_LOG_PREFIX_NAME: unset
BIOME_CONFIG_PATH: unset
BIOME_THREADS: unset
NO_COLOR: unset
TERM: tmux-256color
JS_RUNTIME_VERSION: v23.9.0
JS_RUNTIME_NAME: node
NODE_PACKAGE_MANAGER: pnpm/10.8.1
Biome Configuration:
Status: Loaded successfully
Path: biome.jsonc
Formatter enabled: false
Linter enabled: true
Assist enabled: true
VCS enabled: false
Workspace:
Open Documents: 0
What happened?
When using a monorepo (ex: Turborepo), aliasing paths does not always work. Instead, the same can be acheived using subpath imports:
https://nodejs.org/api/packages.html#subpath-imports
Essentially instead of a predefined alias like @ or ~, subpath imports uses a # symbol.
When used with biomejs, the noImportCycles does not pick up on the circular dependency.
This can be tested simply by creating a circular dependency import: a -> b -> a
When importing using the relative path that subpath imports allows, example:
Assuming both are exported in the same barrel file
// In 'A'
import { B } from '#lib'
// in 'B'
import { A } from '#lib`
^ Biome does not pick up on this being a problem
Where as if you change it to:
// In 'A'
import { B } from './lib'
// in 'B'
import { A } from './lib`
^ This is picked up by Biome
How to test
This can be tested/reproduced in the following repository:
https://github.com/npearson72/example-biome-bug
Steps to reproduce:
git clone [email protected]:npearson72/example-biome-bug.git
pnpm i
Then run either of the following commands:
pnpm lint
-- OR --
pnpm --filter @example/example-package lint
-- OR --
cd packages/example-package && pnpm exec biome lint
In this repo, I have several examples in packages/example-package/src/lib
You'll notice the following files:
A <-> B point to each using ./lib/B and ./lib/Arespectfully.
C <-> D point to each using #lib/D and #lib/C respectfully.
Either of these import styles (i.e. ./lib or #lib should reference the identical path.
However, when you run biome lint, only A and B errors are picked up:
src/lib/A.tsx:1:19 lint/nursery/noImportCycles ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ This import is part of a cycle.
> 1 │ import { B } from './A';
│ ^^^^^
2 │
3 │ export const A = () => {
ℹ This import resolves to src/lib/A.tsx
... which imports src/lib/A.tsx
... which is the file we're importing from.
src/lib/B.tsx:1:19 lint/nursery/noImportCycles ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ This import is part of a cycle.
> 1 │ import { A } from './B';
│ ^^^^^
2 │
3 │ export const B = () => {
ℹ This import resolves to src/lib/B.tsx
... which imports src/lib/B.tsx
... which is the file we're importing from.
Checked 7 files in 99ms. No fixes applied.
Found 2 errors.
NOTE: This bug was originally reported here #7191, but was closed before I was able to get an example repo prepared.
Expected result
I would expect it to understand subpath imports and treat them like any other path to detect circular dependencies.
Code of Conduct
Environment information
What happened?
When using a monorepo (ex: Turborepo), aliasing paths does not always work. Instead, the same can be acheived using subpath imports:
https://nodejs.org/api/packages.html#subpath-imports
Essentially instead of a predefined alias like
@or~, subpath imports uses a#symbol.When used with biomejs, the
noImportCyclesdoes not pick up on the circular dependency.This can be tested simply by creating a circular dependency import: a -> b -> a
When importing using the relative path that subpath imports allows, example:
Assuming both are exported in the same barrel file
^ Biome does not pick up on this being a problem
Where as if you change it to:
^ This is picked up by Biome
How to test
This can be tested/reproduced in the following repository:
https://github.com/npearson72/example-biome-bug
Steps to reproduce:
git clone [email protected]:npearson72/example-biome-bug.gitpnpm iThen run either of the following commands:
pnpm lint-- OR --
pnpm --filter @example/example-package lint-- OR --
cd packages/example-package && pnpm exec biome lintIn this repo, I have several examples in
packages/example-package/src/libYou'll notice the following files:
A.tsxB.tsxC.tsxD.tsxA<->Bpoint to each using./lib/Band./lib/Arespectfully.C<->Dpoint to each using#lib/Dand#lib/Crespectfully.Either of these import styles (i.e.
./libor#libshould reference the identical path.However, when you run
biome lint, onlyAandBerrors are picked up:NOTE: This bug was originally reported here #7191, but was closed before I was able to get an example repo prepared.
Expected result
I would expect it to understand subpath imports and treat them like any other path to detect circular dependencies.
Code of Conduct