eslint-plugin-import
eslint-plugin-import copied to clipboard
import/no-unresolved does not report none-existing function in Yarn workspace
I noticed that import/no-unresolved is not warning me when I forgot to export a function from a Yarn workspace which will be imported from another Yarn workspace.
I created a minimal repo https://github.com/chrisdoc/eslint-plugin-import-bug-minimal-repo which consists of two workspaces foo and bar.
.
├── .eslintrc.js
├── .gitignore
├── bar
│ ├── index.js
│ └── package.json
├── foo
│ ├── index.js
│ └── package.json
├── LICENSE
├── package.json
├── README.md
└── yarn.lock
Inside foo/index.js there is a single function helloFoo which is exported so that it can be consumed by bar
function helloFoo() {
// eslint-disable-next-line no-console
console.log('hello foo');
}
module.exports = { helloFoo };
Now in bar/index.js I import both helloFoo and a none existing helloFooV2 via:
const { helloFoo, helloFooV2 } = require('@my/foo');
Now when I run yarn lint no errors are reported:
yarn lint
yarn run v1.22.4
$ eslint .
✨ Done in 1.23s.
When I then try to execute yarn bar which calls bar/index.js NodeJS fails due to calling helloFooV2 which does not exist.
yarn run v1.22.4
$ yarn workspace @my/bar start
$ node index.js
hello foo
/Users/chrisdoc/dev/eslint-plugin-import-bug-minimal-repo/bar/index.js:4
helloFooV2();
^
TypeError: helloFooV2 is not a function
at Object.<anonymous> (/Users/chrisdoc/dev/eslint-plugin-import-bug-minimal-repo/bar/index.js:4:1)
at Module._compile (internal/modules/cjs/loader.js:956:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
at Module.load (internal/modules/cjs/loader.js:812:32)
at Function.Module._load (internal/modules/cjs/loader.js:724:14)
at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
at internal/main/run_main_module.js:17:11
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed.
Exit code: 1
Command: /Users/chrisdoc/.nvm/versions/node/v12.13.0/bin/node
Arguments: /Users/chrisdoc/.yarn/lib/cli.js start
Directory: /Users/chrisdoc/dev/eslint-plugin-import-bug-minimal-repo/bar
Output:
info Visit https://yarnpkg.com/en/docs/cli/workspace for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Here you can see an example being run on Github Workflows that shows that yarn lint succeeds and that yarn bar fails
https://github.com/chrisdoc/eslint-plugin-import-bug-minimal-repo/runs/787914292
I assume this is because the ExportMap doesn't traverse symlinks - does it fail as expected when things are installed, not symlinked in?
I have the same issue in monorepo. import/named doesn't check private yarn workspaces.
@SanjiKir you'd have to provide a custom resolver if you have a custom layout, including any "workspaces" things.
@ljharb can expand further on what my custom resolver would need to do please?! i'm having the same issue, @SanjiKir did you get yours working?
@jd2rogers2 anything that doesn’t match standard node resolution has to tell this plugin how to resolve files.
In this specific case, no-unresolved isn’t the issue, since the file resolves; it’d be a different rule that should be warning on a missing export from a present file.
@jd2rogers2 anything that doesn’t match standard node resolution has to tell this plugin how to resolve files.
In this specific case, no-unresolved isn’t the issue, since the file resolves; it’d be a different rule that should be warning on a missing export from a present file.
@ljharb right, i'm getting input/named false negatives (lack of error when i'd expect there to be one)
i have import { DoesntExist } from 'react-dom'; but not getting an error
and
module.exports = {
env: {
browser: true,
'cypress/globals': true,
es6: true,
'jest/globals': true,
},
extends: [
'eslint:recommended',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:import/typescript',
'airbnb',
'plugin:react/recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: [
'cypress',
'jest',
'react',
'@typescript-eslint',
'import',
],
rules: {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/member-delimiter-style': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'arrow-parens': ['error', 'as-needed'],
'import/extensions': ['error', 'never'],
'import/prefer-default-export': ['off'],
'import/no-cycle': ['off'],
'import/no-unresolved': 2,
'import/named': 2,
'max-len': ['error', { 'code': 100 }],
'no-multiple-empty-lines': ['error', { max: 2 }],
'no-unused-vars': 'off',
'react/jsx-filename-extension': ['error', { extensions: ['.tsx'] }],
'react/jsx-one-expression-per-line': ['off'],
'react/jsx-props-no-spreading': ['off'],
'react/prop-types': 0,
'react/require-default-props': ['error', { ignoreFunctionalComponents: true }],
},
settings: {
// 'import/extensions': ['.js', '.jsx', '.ts', '.tsx'],
'import/resolver': {
node: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
// 'typescript': { extensions: ['.ts', '.tsx'] },
},
'import/internal-regex': [
'^node_modules/@premisedata',
'^node_modules/portal',
'^packages/apps/portal/',
'^packages/apps/stories/',
'^packages/apps/tools/',
'^packages/apps/web-api/',
'^packages/libs/base-ui/',
],
}
};
(not exactly in the best shape as i've been trying a bunch of stuff but i would still expect those named errors)
am i wrong in assuming that it should fail for node_modules too?
You aren't wrong. Could you file a new issue for that, since I think it's not related to this issue?