[Fix] importType: correctly classify aliases resolving outside package root#3228
Merged
ljharb merged 1 commit intoimport-js:mainfrom Feb 19, 2026
Merged
Conversation
…age root Fixes import-js#496. When a resolver (e.g., webpack, typescript) resolves an aliased import to a path outside the current package root but NOT in node_modules (e.g., a monorepo sibling package), `isExternalPath` previously classified it as 'external' because any path with a relative prefix of '..' was treated as external. This caused `no-extraneous-dependencies` to report false positives for these imports. The fix replaces the blanket "outside package root = external" check in `isExternalPath` with a more targeted approach: 1. Check if the path is under a configured external-module-folder relative to the package (preserves existing behavior for local node_modules) 2. For paths outside the package root, check if the external-module-folder appears as a path segment (catches hoisted deps in monorepos) Also updates `isInternalPath` to be the logical complement of `isExternalPath` for resolved paths, so any successfully resolved path that is not in an external module folder is correctly classified as 'internal'. Co-authored-by: Cursor <cursoragent@cursor.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3228 +/- ##
==========================================
+ Coverage 90.69% 95.77% +5.07%
==========================================
Files 83 83
Lines 3688 3688
Branches 1331 1331
==========================================
+ Hits 3345 3532 +187
+ Misses 343 156 -187 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
ljharb
approved these changes
Feb 10, 2026
Member
ljharb
left a comment
There was a problem hiding this comment.
assuming the tests fail without the fix, and pass with, this looks great, thanks!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #496.
When a resolver (e.g., webpack, typescript) resolves an aliased import to a path outside the current package root but not in
node_modules(e.g., a monorepo sibling package or a workspace alias target),isExternalPathpreviously classified it as'external'because any path with a relative prefix of..from the package root was treated as external. This causedno-extraneous-dependencies(and other rules usingimportType) to report false positives for these imports.Root Cause
In
src/core/importType.js,isExternalPath()had an overly aggressive first check:This correctly catches hoisted
node_modulesin monorepos, but incorrectly catches:Fix
The fix replaces the blanket "outside package root = external" check with a more targeted approach:
external-module-folderrelative to the package — preserves existing behavior for localnode_modulesexternal-module-folderappears as a path segment — catches hoisted deps (e.g.,/monorepo/node_modules/lodash) but NOT sibling packages (e.g.,/monorepo/packages/shared/src)Also updates
isInternalPathto be the logical complement ofisExternalPathfor resolved paths, so any successfully resolved path that is not in an external module folder is correctly classified as'internal'.Example scenario
Test plan
tests/files/alias-outside-package/package.jsonto create a sub-package boundaryimportTypetest: alias that resolves outside the package root but not innode_modules→'internal'no-extraneous-dependenciesvalid test: aliased import from outside package root is not flagged