import-js / eslint-plugin-import

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

`named` rule not working #901

Open jamesob opened 7 years ago

jamesob commented 7 years ago

Hi,

First off, thanks for the great plugin. The named rule doesn't seem to be working for me (at least as expected) while others do.

Context

package.json

 $ egrep 'eslint-.*import' package.json

    "eslint-import-resolver-webpack": "^0.8.3",
    "eslint-plugin-import": "^2.7.0",

.eslintrc

{
    "parser": "babel-eslint",
    ...
    "settings": {
        ...
        "import/resolver": {
            "webpack": {
                "config": "webpack.prod.config.js"
            }
        }
    },
    ...
    "extends": [
         ...
        "plugin:import/errors",
        "plugin:import/warnings"
    ],
    "rules": {
        "max-len": ["error", 80, 2, { "ignoreUrls": true }],

        // Don't warn us about using console.log (though that should only
        // happen in the dev environment).
        "no-console": [0]
    },
    ...
}

Issue

I've got a file with the following contents

import { logToSentry, butts } from './errors'

const errorAlert = (msg, err) => {
  logToSentry(msg, err);
  butts();
}

As you can probably imagine, butts doesn't exist in ./errors and certainly isn't exported. Eslint raises no issue about this.

However, I know that eslint-plugin-import is doing something because if I change ./errors to a path that doesn't exist, I get the following output from eslint:

/code/actions.jsx
  5:36  error  Unable to resolve path to module './errorsDoesntExist'  import/no-unresolved

✖ 1 problem (1 error, 0 warnings)

So why would one rule be working (import/no-unresolved) but not the other (import/named)? Any guidance is much appreciated.

ljharb commented 7 years ago

What does errors.js look like?

jamesob commented 7 years ago

errors.js

import Raven from 'raven-js';

/**
 * If `err` is truthy, log it to Sentry along with optional information
 * about the state of the application.
 */
export const logToSentry = (
    err, wrappedErr = null, action = null, state = null, extra = null) => {
  if (!err) return;

  __DEV__ && console.log("[sentry] logging error", err, wrappedErr);

  Raven.captureException(err, {
    extra: { wrappedError: wrappedErr, action, ...extra }
  });
}
fvclaus commented 7 years ago

I am experiencing the same issue. Have you found a solution yet?

conundrumer commented 6 years ago

I figured out how to reproduce this. The named rule doesn't work for files with no exports. Workaround: ensure that all files have some export.

Example:

entry.js:

import { foo, nonExistent } from './dep.js'
import { nothing } from './empty.js'

dep.js: (correct)

export const foo = 'bar'

empty.js: (incorrect)

console.log('no exports to be found here')

command

$ eslint entry.js

entry.js
  1:15  error  nonExistent not found in './dep.js'  import/named

✖ 1 problem (1 error, 0 warnings)

nothing doesn't get reported as "not found" under import/named

ljharb commented 6 years ago

@conundrumer thanks!

That sounds like a bug we need to fix - that a file with no exports and also no module.exports = and also no mutations of exports should be considered as exporting nothing.

j-f1 commented 6 years ago

@conundrumer It looks like that’s happening because empty.js has the default scriptType of script, and since it’s not possible to statically determine exports from a script file, it probably assumes everything is OK. (If you add export {} to empty.js to make it have ascriptType of module, you should get the error as expected)

mdecurtins commented 3 years ago

Has there really been no progress on this in almost 3 years?

I just ran into this; saw a sudden strange occurrence of TypeError: Object(...) is not a function, saw that it pointed back to a couple of GraphQL queries with the gql tag, and then I finally realized that I forgot that it's import gql from 'graphql-tag, not import { gql } from graphql-tag. I wondered why ESLint wasn't picking this up, because I do have import/named: 2 in my .eslintrc.js file, and then I found this issue. Since I don't control this dependency I can't just go in and change its export.

Any suggestions for workarounds appreciated.

ljharb commented 3 years ago

@mdecurtins the passage of time doesn't change the availability of people to work on it. Nobody's submitted a PR yet.

mdecurtins commented 3 years ago

That was meant more to express surprise; after all, there are huge numbers of projects using this package, and I'm sure the cases that get trapped up in this bug are not uncommon. Anyway, thanks for your comment.

andrewzey commented 1 year ago

https://github.com/import-js/eslint-plugin-import/issues/2005#issuecomment-1646654313