import-js / eslint-plugin-import

ESLint plugin with rules that help validate proper imports.
MIT License
5.57k stars 1.57k forks source link

`import/extensions`, `import/no-unresolved` don't highlight import of nonexistent .js in TypeScript project #3015

Open jwbth opened 5 months ago

jwbth commented 5 months ago

Take this simple setup:

eslint.config.js

import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import * as pluginImport from 'eslint-plugin-import';

export default [
  eslint.configs.recommended,
  ...tseslint.configs.recommended,
  {
    files: ['**/*.ts'],
    plugins: {
      'import': pluginImport,
    },
    settings: {
      'import/resolver': {
        node: true,
        typescript: true,
      },
    },
    rules: {
      'import/extensions': 'error',
      'import/no-unresolved': 'error',
    },
  },
];

index.ts

import { num } from './exported.js';

exported.ts

export const num = 3;

In index.ts, ./exported.js points to a nonexistent file. Neither import/extensions, nor import/no-unresolved highlight it though.

I narrowed down the problem to typescript: true – as soon as I comment that line, I see both errors:

Unexpected use of file extension "js" for "./exported.js" eslint(import/extensions) Unable to resolve path to module './exported.js'. eslint(import/no-unresolved)

I assume it may be something to do with the eslint-import-resolver-typescript package, so I tried messing with it in some ways, but to no avail.

ljharb commented 5 months ago

try changing

      'import/resolver': {
        node: true,
        typescript: true,
      },

to:

      'import/resolver': {
        typescript: true,
        node: true,
      },
jwbth commented 5 months ago

No effect, unfortunately.

jwbth commented 5 months ago

I should also note that the highlight will appear also if:

So, this seems to be a pretty unique case with a nonexistent .js silently mapping to an existent .ts with the same basename.

dmitryshelomanov commented 4 months ago

@ljharb did you solve it ?

alexgwolff commented 4 months ago

try changing

      'import/resolver': {
        node: true,
        typescript: true,
      },

to:

      'import/resolver': {
        typescript: true,
        node: true,
      },

This works to me

ljharb commented 4 months ago

Certainly you'd basically always want node to be last in that object.

guillaumebrunerie commented 1 month ago

How is the order of the keys in an object relevant? As far as I know, there is nothing in the ECMAScript specification that guarantees anything about the order of the keys in an object. In particular Object.keys and friends do not guarantee returning the keys in any particular order.

ljharb commented 1 month ago

@guillaumebrunerie that's actually false; since 2015 (ES6) object key ordering has been deterministic (modulo "insertion order"), and yes Object.keys and friends all guarantee that.

guillaumebrunerie commented 1 month ago

@guillaumebrunerie that's actually false; since 2015 (ES6) object key ordering has been deterministic (modulo "insertion order"), and yes Object.keys and friends all guarantee that.

Ah indeed, my bad, not sure why I thought it was still unspecified.