fix(linter): Update import/no-named-as-default to allow named import if equivalent to the default import#19100
Conversation
There was a problem hiding this comment.
Pull request overview
Updates Oxlint’s import/no-named-as-default rule to match upstream eslint-plugin-import behavior by not flagging default imports whose local name matches a named export when the module’s default and named exports are effectively the same re-export (fixes #19099).
Changes:
- Add special-case logic to skip the warning when default + named exports are re-exported from the same source binding.
- Add fixtures and test cases to cover the allowed and still-disallowed scenarios.
- Update the snapshot output to include the new failing case.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| crates/oxc_linter/src/rules/import/no_named_as_default.rs | Implements the new “same re-export” exception and adds corresponding tests. |
| crates/oxc_linter/src/snapshots/import_no_named_as_default.snap | Updates snapshots to reflect the added test case. |
| crates/oxc_linter/fixtures/import/re-export-default-and-named.js | Fixture for the allowed scenario (default + named re-exported from same source). |
| crates/oxc_linter/fixtures/import/re-export-default-and-named-source.js | Source fixture providing the shared binding. |
| crates/oxc_linter/fixtures/import/re-export-default-and-named-misleading.js | Fixture for the disallowed scenario (default + named re-exported from different sources). |
CodSpeed Performance ReportMerging this PR will not alter performanceComparing Summary
Footnotes
|
|
@connorshea I added an extra test case here: 12801d4 It currently passes, but i think it should report an error - am i right? let me know and I can either fix it or revert the commit, thanks 🙏 |
|
You are correct I believe, yeah. I'll work on fixing this. |
|
Added two more test cases to ensure this fix doesn't cause any unintended problems with any of these situations. Should be good to go now. |
Merge activity
|
…t if equivalent to the default import (#19100) Fixes #19099. The way this logically works is a bit weird, but basically the idea is that some libraries have exports done via re-export of the same identifier as both a named _and_ default export. In that case, we should allow `import name from 'foo.js';` *and* `import { name } from 'foo.js';`. This allows the rule to better match the upstream rule's behavior. Confirmed by running the built binary from this branch against [my issue reproduction repo](https://github.com/connorshea/oxlint-repro-default-export/blob/main/test.js) and confirming it no longer had any violations. ```js /* * This is what the @testing-library/user-event package exports: * ```js * export { userEvent as default } from './setup'; * export { userEvent } from './setup'; * ``` * * It should not error when we import the default export as `userEvent`, because it refers to the same exact value as if we had imported it via `import { userEvent } from '@testing-library/user-event';`. */ import userEvent from '@testing-library/user-event'; // With oxlint 1.43.0 and earlier, it currently gets reported as a violation. The original ESLint rule does not report this. ``` AI Disclosure: Built with Claude Code, Opus 4.6. Based on [the changes from the upstream rule](https://github.com/import-js/eslint-plugin-import/pull/3032/changes).
934944d to
31b562f
Compare
…t if equivalent to the default import (oxc-project#19100) Fixes oxc-project#19099. The way this logically works is a bit weird, but basically the idea is that some libraries have exports done via re-export of the same identifier as both a named _and_ default export. In that case, we should allow `import name from 'foo.js';` *and* `import { name } from 'foo.js';`. This allows the rule to better match the upstream rule's behavior. Confirmed by running the built binary from this branch against [my issue reproduction repo](https://github.com/connorshea/oxlint-repro-default-export/blob/main/test.js) and confirming it no longer had any violations. ```js /* * This is what the @testing-library/user-event package exports: * ```js * export { userEvent as default } from './setup'; * export { userEvent } from './setup'; * ``` * * It should not error when we import the default export as `userEvent`, because it refers to the same exact value as if we had imported it via `import { userEvent } from '@testing-library/user-event';`. */ import userEvent from '@testing-library/user-event'; // With oxlint 1.43.0 and earlier, it currently gets reported as a violation. The original ESLint rule does not report this. ``` AI Disclosure: Built with Claude Code, Opus 4.6. Based on [the changes from the upstream rule](https://github.com/import-js/eslint-plugin-import/pull/3032/changes).
# Oxlint ### 🚀 Features - ebb80b3 ast: Add `node_id` field to all AST struct nodes (#18138) (Boshen) - 2879fc5 linter: Implement fixer for unicorn/prefer-math-trunc (#19275) (camc314) - a204eda linter: Implement fixer for unicorn/no-typeof-undefined (#19274) (camc314) - ab46d9c linter: Implement typescript/class-literal-property-style (#19252) (Vincent R) - 1a61f58 linter: Implement typescript/no-invalid-void-type (#19242) (Vincent R) ### 🐛 Bug Fixes - 45adda2 oxlint/lsp: Use blocking stdio in Oxlint (#19292) (overlookmotel) - 05bc855 linter/import: Count unique module sources in max-dependencies (#19270) (camc314) - 8566b44 linter: Check for preceeding token in math trunc fixer (#19277) (camc314) - f16f2b6 linter/import-no-cycle: Avoid traversal-order false negatives with type-only edges (#19267) (camc314) - d4937e7 linter: Recognize module-scoped callback refs as stable in exhaustive-deps (#19220) (Sreetam Das) - 140c9bd linter: Detect fallthrough from `default` when it is not the last case (#19261) (Boshen) - 740a009 linter: Accept digits after 'use' in hook names (#19254) (Sreetam Das) - 31b562f linter: Update `import/no-named-as-default` to allow named import if equivalent to the default import (#19100) (connorshea) - 79c82cc linter: Avoid applying object-level docs to nested object methods in require-param (#19231) (camc314) ### ⚡ Performance - 5670291 linter/class-literal-property-style: Avoid unneeded string allocations (#19262) (camc314) # Oxfmt ### 🚀 Features - ebb80b3 ast: Add `node_id` field to all AST struct nodes (#18138) (Boshen) ### 🐛 Bug Fixes - 1957908 formatter: Avoid unnecessary parentheses for string literal in labeled statement (#19272) (Dunqing) Co-authored-by: camc314 <[email protected]>
…t if equivalent to the default import (oxc-project#19100) Fixes oxc-project#19099. The way this logically works is a bit weird, but basically the idea is that some libraries have exports done via re-export of the same identifier as both a named _and_ default export. In that case, we should allow `import name from 'foo.js';` *and* `import { name } from 'foo.js';`. This allows the rule to better match the upstream rule's behavior. Confirmed by running the built binary from this branch against [my issue reproduction repo](https://github.com/connorshea/oxlint-repro-default-export/blob/main/test.js) and confirming it no longer had any violations. ```js /* * This is what the @testing-library/user-event package exports: * ```js * export { userEvent as default } from './setup'; * export { userEvent } from './setup'; * ``` * * It should not error when we import the default export as `userEvent`, because it refers to the same exact value as if we had imported it via `import { userEvent } from '@testing-library/user-event';`. */ import userEvent from '@testing-library/user-event'; // With oxlint 1.43.0 and earlier, it currently gets reported as a violation. The original ESLint rule does not report this. ``` AI Disclosure: Built with Claude Code, Opus 4.6. Based on [the changes from the upstream rule](https://github.com/import-js/eslint-plugin-import/pull/3032/changes).
# Oxlint ### 🚀 Features - ebb80b3 ast: Add `node_id` field to all AST struct nodes (oxc-project#18138) (Boshen) - 2879fc5 linter: Implement fixer for unicorn/prefer-math-trunc (oxc-project#19275) (camc314) - a204eda linter: Implement fixer for unicorn/no-typeof-undefined (oxc-project#19274) (camc314) - ab46d9c linter: Implement typescript/class-literal-property-style (oxc-project#19252) (Vincent R) - 1a61f58 linter: Implement typescript/no-invalid-void-type (oxc-project#19242) (Vincent R) ### 🐛 Bug Fixes - 45adda2 oxlint/lsp: Use blocking stdio in Oxlint (oxc-project#19292) (overlookmotel) - 05bc855 linter/import: Count unique module sources in max-dependencies (oxc-project#19270) (camc314) - 8566b44 linter: Check for preceeding token in math trunc fixer (oxc-project#19277) (camc314) - f16f2b6 linter/import-no-cycle: Avoid traversal-order false negatives with type-only edges (oxc-project#19267) (camc314) - d4937e7 linter: Recognize module-scoped callback refs as stable in exhaustive-deps (oxc-project#19220) (Sreetam Das) - 140c9bd linter: Detect fallthrough from `default` when it is not the last case (oxc-project#19261) (Boshen) - 740a009 linter: Accept digits after 'use' in hook names (oxc-project#19254) (Sreetam Das) - 31b562f linter: Update `import/no-named-as-default` to allow named import if equivalent to the default import (oxc-project#19100) (connorshea) - 79c82cc linter: Avoid applying object-level docs to nested object methods in require-param (oxc-project#19231) (camc314) ### ⚡ Performance - 5670291 linter/class-literal-property-style: Avoid unneeded string allocations (oxc-project#19262) (camc314) # Oxfmt ### 🚀 Features - ebb80b3 ast: Add `node_id` field to all AST struct nodes (oxc-project#18138) (Boshen) ### 🐛 Bug Fixes - 1957908 formatter: Avoid unnecessary parentheses for string literal in labeled statement (oxc-project#19272) (Dunqing) Co-authored-by: camc314 <[email protected]>
Fixes #19099. The way this logically works is a bit weird, but basically the idea is that some libraries have exports done via re-export of the same identifier as both a named and default export. In that case, we should allow
import name from 'foo.js';andimport { name } from 'foo.js';. This allows the rule to better match the upstream rule's behavior.Confirmed by running the built binary from this branch against my issue reproduction repo and confirming it no longer had any violations.
AI Disclosure: Built with Claude Code, Opus 4.6. Based on the changes from the upstream rule.