Skip to content

extensions: treat relative package roots as packages for ignorePackages#3261

Open
morgan-coded wants to merge 5 commits into
import-js:mainfrom
morgan-coded:fix/2844-extensions-relative-package-ignore
Open

extensions: treat relative package roots as packages for ignorePackages#3261
morgan-coded wants to merge 5 commits into
import-js:mainfrom
morgan-coded:fix/2844-extensions-relative-package-ignore

Conversation

@morgan-coded

Copy link
Copy Markdown

Problem I saw:
import/extensions could still report . or .. as missing an extension even when ignorePackages was enabled.
Those relative imports can point at a directory that is itself a package root, but the rule only gave package treatment to external or scoped imports. Thanks @benasher44 for filing the follow-up from #2778.

What I changed:
I added a narrow package-root check for relative . and .. imports.
When one of those specifiers resolves to a package root, it now follows the same ignorePackages behavior as package imports. I kept the scope to ignorePackages and did not broaden the ambiguous always plus relative-import case.

How I checked it:
I moved the existing TODO cases into valid first and got the expected red run: 69 passing, 2 failing.
After the fix, the extensions rule suite passed with 71 passing and 0 failing. The full repo suite also passed with 3029 passing, 0 failing, and 1 pending. Lint passed on the changed files, and pre-push hygiene is clean.

Closes #2844

Copilot AI review requested due to automatic review settings June 4, 2026 20:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates the extensions rule to avoid false positives when ignorePackages is enabled and a relative import resolves to a directory that is itself a package root (has its own package.json), aligning behavior with issue #2844.

Changes:

  • Added logic to detect relative specifiers that resolve to a package root directory and treat them as packages.
  • Updated rule tests to mark these relative package-root imports as valid under ignorePackages.
  • Documented the fix in the changelog and added the issue reference link.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
tests/src/rules/extensions.js Moves previously-failing relative package-root cases into valid for ignorePackages.
src/rules/extensions.js Adds isRelativeToPackage() and integrates it into the “is this a package?” decision.
CHANGELOG.md Notes the fix and adds a link to issue #2844.
Comments suppressed due to low confidence (1)

src/rules/extensions.js:1

  • Operator precedence here makes isScoped(importPath) and isRelativeToPackage(importPath, context) apply even when ignorePackages is false. That causes scoped imports / relative package-root imports to be treated as packages unconditionally, which can incorrectly skip extension enforcement. Wrap the OR-conditions inside the ignorePackages && (...) group so the package-ignoring behavior only activates when ignorePackages is enabled.
import path from 'path';

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/rules/extensions.js Outdated
Comment on lines +100 to +114
function isRelativeToPackage(importPath, context) {
if (!(/^[.]{1,2}([\\/]|$)/).test(importPath)) {
return false;
}
const physicalFilename = getPhysicalFilename(context);
if (!physicalFilename || physicalFilename === '<text>') {
return false;
}
const targetPath = path.resolve(path.dirname(physicalFilename), importPath);
try {
return getFilePackagePath(targetPath) === targetPath;
} catch (e) {
return false;
}
}
@codecov

codecov Bot commented Jun 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.74%. Comparing base (b3cf7e1) to head (756267d).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3261      +/-   ##
==========================================
- Coverage   95.82%   95.74%   -0.09%     
==========================================
  Files          83       83              
  Lines        3741     3759      +18     
  Branches     1355     1359       +4     
==========================================
+ Hits         3585     3599      +14     
- Misses        156      160       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ljharb ljharb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit skeptical of non-breaking-change PRs that change existing tests. can you try to minimize the diff on existing tests?

@morgan-coded

Copy link
Copy Markdown
Author

That makes sense. I reworked the tests so the existing TODO cases are just moved verbatim from invalid to valid, with the extra fallback coverage added separately.

Focused suite, full tests-only, lint, diff-check, and hygiene are all clean.

@ljharb ljharb reopened this Jun 15, 2026
@morgan-coded morgan-coded force-pushed the fix/2844-extensions-relative-package-ignore branch from 080a364 to e9a634b Compare June 15, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

[import/extensions] ".." and "." import paths are incorrectly flagged as requiring an extension, when either is al local package

3 participants