linter: eslint-plugin-import(extensions) false positives with missing extension
What version of Oxlint are you using?
1.6.0
What command did you run?
oxlint -c .oxlintrc.json test.ts
What does your .oxlintrc.json config file look like?
{
"env": {
"browser": true,
"node": true
},
"plugins": [
"import"
],
"rules": {
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"ts": "never"
}
]
}
}
What happened?
Import extensions are always required for non-package paths (relative, aliased) since #11872.
With ESLint and eslint-plugin-import, there are no errors when extension is missing.
Continuing from #11818.
Code
import { Package } from 'vue'; // OK, ignorePackages
import { A } from './something.hooks'; // OK
import { B } from './something.ts'; // OK, File extension "ts" should not be included in the import declaration.
import { C } from './something'; // Error, Missing file extension in import declaration
import { D } from '~/common/something'; // Error, Missing file extension in import declaration
oxlint output
❯ oxlint -c .oxlintrc.json test.ts
× eslint-plugin-import(extensions): Missing file extension in import declaration
╭─[test.ts:4:1]
3 │
4 │ import { C } from './something'; // Error, Missing file extension in import declaration
· ────────────────────────────────
5 │ import { D } from '~/common/something'; // Error, Missing file extension in import declaration
╰────
help: Add a file extension to this import.
× eslint-plugin-import(extensions): File extension "ts" should not be included in the import declaration.
╭─[test.ts:2:1]
1 │ import { A } from './something.hooks'; // OK
2 │ import { B } from './something.ts'; // OK, File extension "ts" should not be included in the import declaration.
· ───────────────────────────────────
3 │
╰────
help: Remove the file extension from this import.
× eslint-plugin-import(extensions): Missing file extension in import declaration
╭─[test.ts:5:1]
4 │ import { C } from './something'; // Error, Missing file extension in import declaration
5 │ import { D } from '~/common/something'; // Error, Missing file extension in import declaration
· ───────────────────────────────────────
╰────
help: Add a file extension to this import.
I don't really understand why the ESLint plugin allows these when the rule is described as such:
If it is the string "ignorePackages", then the rule enforces the use of extensions for all import statements except package imports.
So maybe oxlint is doing the right thing but it's a different behaviour in our setup.
It might also be caused by aliases but it also ignores missing extensions for relative imports.
Unfortunately, in more advanced linting setups, such as when employing custom specifier aliases (e.g. you're using eslint-import-resolver-alias, paths in tsconfig.json, etc), this rule can be too coarse-grained when determining which imports to ignore and on which to enforce the config
I can't really seem to reproduce the issue in our project anymore.
I am experiencing this issue, was this bug reintroduced somehow?
I'll reopen because it still happens occasionally.
The basics seem to be that oxlint always expects an extension while ESLint is more lax about it since it has resolving capabilities.
For now I’ve just setup my oxlint/eslint config to handle this rule with eslint but obviously that’s not ideal.
The option ignorePackages seems like to not be used.
For example, I've got the issue with the following import:
import { fn } from "storybook/test"
We want to enforce usage of extensions to follow module resolution standard, and have false positives:
"import/extensions": [
"error",
"always",
{
"ignorePackages": true,
"checkTypeImports": true
}
],
import "foo"; // ok
import "foo/bar"; // fails - unexpected
import "./foo"; // fails - as expected
import "./foo.ts" // ok
import { createContext } from 'preact/compat' // error - unexpected
import { signal } from "@preact/signals"; // ok - as expected
Same here, though I am not even sure I understand what the correct syntax is. I tried many variants, including this monstrosity below, but there is a bug going on, right?:
"import/extensions": [
"error",
"ignorePackages",
{ "js": "ignorePackages", "ts": "ignorePackages", "ignorePackages": true }
],
Were fix(linter/extensions): false positives with non configured extensions by camc314 · Pull Request #11872 · oxc-project/oxc and fix(linter): fix false positives reported when analyzing package imports by taearls · Pull Request #14602 · oxc-project/oxc supposed to fix it? One of them looks merged, but it's still bugging on "import type { LibSQLDatabase } from 'drizzle-orm/libsql';" for example in today's 1.25.0.
Marked this as higher priority since it seems to be a problem effecting a few folks and I seem to be seeing this issue when testing repos like mastodon as well when experimenting with oxlint on it
If anyone can provide simple reproduction repo(s) of problematic behavior that'd be incredibly helpful for testing purposes. Preferably, with both ESLint and oxlint to show the discrepancies.
Potentially related to problems with this rule, including a repro case of the issue with ignorePackages not working correctly: https://github.com/oxc-project/oxc/issues/11881