import-js / import-js/eslint-plugin-import
[no-extraneous-dependencies] relative path that refers to file outside package.json should error
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 5.9k
- Forks
- 1.5k
- PR merge metrics
- No merged PRs in 30d
Description
Hi, I'm not sure if the current behavior is intended or not, so I want to start a discussion.
Simple setup
Directory
src/
├── package.json
├── node_modules/
├── .eslintrc.json
├── tsconfig.json
├── client/
├── server/
│ ├── package.json
│ ├── node_modules/
│ └── index.ts
└── shared/
└── util.ts
tsconfig
{
"compilerOptions": {
"paths": {
"@/utils/*": ["./utils/*"]
}
}
eslint
"import/no-extraneous-dependencies": ["error", { "packageDir": [".", "./server"] }],
Example 1 with TS Path Alias: Errors as expected
However, the below uses the typescript path alias, which does error. In this case, the plugin resolves it as an external import. https://github.com/import-js/eslint-plugin-import/blob/main/src/core/importType.js#L100
// src/server/index.ts
import util from '@/shared/util';
Example 2 with relative import: No error (Bug?)
When doing the following, there is no error from the rule. This is because the plugin considers it a parent import. https://github.com/import-js/eslint-plugin-import/blob/main/src/core/importType.js#L97
// src/server/index.ts
import util from '../shared/util';
Discussion
I'm not sure I agree with the discrepancy in the above behavior. It doesn't really make sense to me that both methods resolve to the same file, but the rule treats them differently. I think using a relative path to refer to a file outside the enclosing package.json context should cause no-extraneous-dependencies to error.
Next Steps / Solution (?)
The core of the issue seems to be that the typeTest() function is overloaded. In this case, it actually seems like it's a bug when used for this rule. In Example 2, typeTest returns "parent", causing the rule to fail to report the error. The correct behavior was actually for typeTest to return "external".
(aside: I think the above bug makes isExternalModule() and isExternalModuleMain() bugged as well)
@ljharb Is the above assessment accurate?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading src/core/importType.js, especially typeTest(), isExternalModule(), and isExternalModuleMain(), then inspect src/rules/no-extraneous-dependencies.js where the result is used. Reproduce the two imports from the issue and review existing rule tests if available. Done means the relative import outside the package.json context is handled consistently with the path-alias case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100