import-js / eslint-plugin-import

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

import/no-unused-modules doesn't work in monorepo #3013

Open saiichihashimoto opened 2 weeks ago

saiichihashimoto commented 2 weeks ago

I'm using a turborepo monorepo and I'm seeing if packages/A/a.ts imports from packages/B/b.ts, the b.ts will have it's exports marked as "not used within other modules".

ljharb commented 2 weeks ago

what's your eslint config?

saiichihashimoto commented 2 weeks ago
eslintrc ```json { "$schema": "https://json.schemastore.org/eslintrc.json", "root": true, "ignorePatterns": ["!.*"], "plugins": [ "eslint-comments", "fp", "import", "lodash-fp", "node", "prefer-arrow", "promise", "unicorn" ], "extends": [ "eslint:recommended", "plugin:@cspell/recommended", "plugin:eslint-comments/recommended", "plugin:fp/recommended", "plugin:import/recommended", "plugin:lodash-fp/recommended", "plugin:node/recommended-module", "plugin:promise/recommended", "plugin:unicorn/recommended", "airbnb" ], "parserOptions": { "ecmaVersion": 11, "sourceType": "module" }, "settings": { "import/extensions": [".js", ".jsx", ".ts", ".tsx"], "import/resolver": { "node": { "extensions": [".js", ".jsx", ".ts", ".tsx"] }, "typescript": { "project": [ "./tsconfig.json", "./@types/tsconfig.json", "./packages/*/tsconfig.json" ] } }, "react": { "version": "detect" } }, "env": { "es6": true }, "rules": { "arrow-body-style": ["error", "as-needed"], "curly": "error", "dot-notation": "error", "eqeqeq": "error", "func-style": ["error", "expression"], "max-classes-per-file": "off", "no-buffer-constructor": "off", "no-caller": "error", "no-constant-binary-expression": "error", "no-else-return": "error", "no-eq-null": "error", "no-extend-native": "error", "no-floating-decimal": "error", "no-implicit-coercion": "error", "no-implied-eval": "error", "no-iterator": "error", "no-lonely-if": "error", "no-loop-func": "error", "no-mixed-operators": "error", "no-multi-assign": "error", "no-nested-ternary": "off", "no-param-reassign": "error", "no-plusplus": "error", "no-return-assign": "error", "no-return-await": "error", "no-script-url": "error", "no-self-compare": "error", "no-sequences": "error", "no-shadow": "off", "no-template-curly-in-string": "error", "no-throw-literal": "error", "no-underscore-dangle": "off", "no-unneeded-ternary": "error", "no-unreachable-loop": "error", "no-unused-expressions": "error", "no-unused-private-class-members": "error", "no-unused-vars": [ "error", { "ignoreRestSiblings": true } ], "no-use-before-define": "error", "no-useless-computed-key": "error", "no-useless-concat": "error", "no-useless-return": "error", "no-var": "error", "no-warning-comments": [ "error", { "terms": ["fixme"], "location": "anywhere" } ], "prefer-arrow-callback": "error", "prefer-const": "error", "prefer-destructuring": "error", "prefer-exponentiation-operator": "error", "prefer-numeric-literals": "error", "prefer-object-spread": "error", "prefer-promise-reject-errors": "error", "prefer-regex-literals": "error", "prefer-rest-params": "error", "prefer-spread": "error", "prefer-template": "error", "radix": "error", "require-atomic-updates": "error", "spaced-comment": "error", "yoda": "error", "@cspell/spellchecker": [ "error", { "autoFix": false, "cspell": { "ignoreRegExpList": ["_key: \".*\"", "_rev: \".*\""], "words": [ "bson", "datetime", "exif", "geopoint", "groq", "hotspot", "lqip", "portabletext", "randexp", "stega", "tsup", "unflow", "unstash", "upserted", "zeplo", "zods" ] } } ], "eslint-comments/disable-enable-pair": [ "error", { "allowWholeFile": true } ], "eslint-comments/no-unused-disable": "error", "eslint-comments/require-description": [ "error", { "ignore": ["eslint-enable"] } ], "fp/no-let": "off", "fp/no-mutating-methods": "off", "fp/no-mutation": "off", "fp/no-nil": "off", "fp/no-rest-parameters": "off", "fp/no-throw": "off", "fp/no-unused-expression": "off", "import/extensions": ["error", "never"], "import/no-absolute-path": "error", "import/no-amd": "error", "import/no-anonymous-default-export": "error", "import/no-commonjs": "error", "import/no-cycle": "error", "import/no-deprecated": "error", "import/no-dynamic-require": "error", "import/no-extraneous-dependencies": [ "error", { "devDependencies": false } ], "import/no-mutable-exports": "error", "import/no-relative-packages": "error", "import/no-self-import": "error", "import/no-useless-path-segments": "error", "import/no-webpack-loader-syntax": "error", "import/order": "off", "import/prefer-default-export": "off", "lodash-fp/consistent-compose": ["error", "flow"], "lodash-fp/no-single-composition": "off", "lodash-fp/preferred-alias": [ "error", { "overrides": [] } ], "node/no-extraneous-import": "off", "node/no-missing-import": "off", "node/no-new-require": "error", "node/no-path-concat": "error", "node/no-process-exit": "error", "node/no-unpublished-import": "off", "node/no-unsupported-features/es-syntax": "off", "node/prefer-global/buffer": "error", "node/prefer-global/console": "error", "node/prefer-global/process": "error", "node/prefer-global/text-decoder": "error", "node/prefer-global/text-encoder": "error", "node/prefer-global/url": "error", "node/prefer-global/url-search-params": "error", "node/prefer-promises/dns": "error", "node/prefer-promises/fs": "error", "prefer-arrow/prefer-arrow-functions": [ "error", { "disallowPrototype": true } ], "promise/no-multiple-resolved": "error", "promise/prefer-await-to-callbacks": "error", "promise/prefer-await-to-then": "error", "promise/valid-params": "off", "react/forbid-prop-types": "off", "unicorn/consistent-function-scoping": [ "error", { "checkArrowFunctions": false } ], "unicorn/explicit-length-check": "off", "unicorn/filename-case": [ "error", { "case": "kebabCase", "ignore": ["^\\[.*\\]\\.tsx$"] } ], "unicorn/import-style": "off", "unicorn/no-array-callback-reference": "off", "unicorn/no-array-method-this-argument": "off", "unicorn/no-array-reduce": "off", "unicorn/no-await-expression-member": "off", "unicorn/no-negated-condition": "off", "unicorn/no-null": "off", "unicorn/no-unreadable-array-destructuring": "off", "unicorn/no-unused-properties": "error", "unicorn/no-useless-undefined": "off", "unicorn/numeric-separators-style": "off", "unicorn/prefer-at": "error", "unicorn/prefer-json-parse-buffer": "error", "unicorn/prefer-node-protocol": "off", "unicorn/prefer-string-replace-all": "error", "unicorn/prevent-abbreviations": "off", "unicorn/require-array-join-separator": "off" }, "overrides": [ { "files": ["**/*.js", "**/*.jsx"], "extends": ["plugin:node/recommended-script"], "env": { "commonjs": true, "es6": false }, "rules": { "fp/no-mutation": [ "error", { "commonjs": true } ], "import/no-commonjs": "off", "node/exports-style": ["error", "module.exports"], "unicorn/prefer-module": "off" } }, { "files": ["**/*.ts", "**/*.tsx"], "plugins": ["@typescript-eslint"], "extends": [ "plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/strict", "plugin:import/typescript", "plugin:typescript-sort-keys/recommended" ], "parser": "@typescript-eslint/parser", "parserOptions": { "project": [ "./tsconfig.json", "./@types/tsconfig.json", "./packages/*/tsconfig.json" ] }, "rules": { "no-loop-func": "off", "no-redeclare": "off", "no-return-await": "off", "no-unused-expressions": "off", "no-unused-vars": "off", "no-use-before-define": "off", "@typescript-eslint/ban-ts-comment": [ "error", { "ts-expect-error": { "descriptionFormat": "^ (TODO|FIXME|EXPECTED) .+$" } } ], "@typescript-eslint/consistent-indexed-object-style": [ "error", "index-signature" ], "@typescript-eslint/consistent-type-definitions": ["error", "type"], "@typescript-eslint/consistent-type-exports": "error", "@typescript-eslint/consistent-type-imports": [ "error", { "fixStyle": "inline-type-imports" } ], "@typescript-eslint/method-signature-style": "error", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/no-explicit-any": [ "off", { "fixToUnknown": true, "ignoreRestArgs": true } ], "@typescript-eslint/no-loop-func": "error", "@typescript-eslint/no-non-null-asserted-optional-chain": "off", "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-redeclare": "error", "@typescript-eslint/no-redundant-type-constituents": "error", "@typescript-eslint/no-require-imports": "error", "@typescript-eslint/no-unused-expressions": "error", "@typescript-eslint/no-unused-vars": [ "error", { "ignoreRestSiblings": true } ], "@typescript-eslint/no-use-before-define": [ "error", { "ignoreTypeReferences": false } ], "@typescript-eslint/no-useless-empty-export": "error", "@typescript-eslint/prefer-regexp-exec": "error", "@typescript-eslint/promise-function-async": "error", "@typescript-eslint/return-await": "error", "@typescript-eslint/sort-type-constituents": "error", "@typescript-eslint/switch-exhaustiveness-check": "error", "import/consistent-type-specifier-style": ["error", "prefer-top-level"] } }, { "files": ["**/*.jsx", "**/*.tsx"], "plugins": ["react", "react-hooks"], "extends": ["plugin:react/recommended", "plugin:react-hooks/recommended"], "parserOptions": { "ecmaFeatures": { "jsx": true } }, "rules": { "react/function-component-definition": [ "error", { "namedComponents": "arrow-function" } ], "react/jsx-filename-extension": [ "error", { "allow": "as-needed", "extensions": [".jsx", ".tsx"] } ], "react/jsx-props-no-spreading": "off", "react/no-danger": "off", "react/no-unstable-nested-components": [ "error", { "allowAsProps": true } ], "react/react-in-jsx-scope": "off" } }, { "files": ["**/*.spec.*", "**/*.test.*"], "extends": [ "plugin:jest-formatting/recommended", "plugin:jest/recommended" ], "env": { "jest": true }, "rules": { "id-length": "off", "@typescript-eslint/consistent-type-imports": "off", "@typescript-eslint/promise-function-async": "off", "import/no-extraneous-dependencies": [ "error", { "devDependencies": true } ], "jest/consistent-test-it": [ "error", { "fn": "it", "withinDescribe": "it" } ], "jest/expect-expect": [ "error", { "assertFunctionNames": ["expect", "expectType"] } ], "jest/no-alias-methods": "error", "jest/no-commented-out-tests": "error", "jest/no-disabled-tests": "error", "jest/no-duplicate-hooks": "error", "jest/no-test-return-statement": "error", "jest/no-untyped-mock-factory": "error", "jest/prefer-called-with": "error", "jest/prefer-comparison-matcher": "error", "jest/prefer-each": "error", "jest/prefer-equality-matcher": "error", "jest/prefer-expect-resolves": "error", "jest/prefer-hooks-in-order": "error", "jest/prefer-hooks-on-top": "error", "jest/prefer-mock-promise-shorthand": "error", "jest/prefer-spy-on": "error", "jest/prefer-strict-equal": "error", "jest/prefer-to-be": "error", "jest/prefer-to-contain": "error", "jest/prefer-to-have-length": "error", "jest/prefer-todo": "error", "jest/require-to-throw-message": "error", "jest/require-top-level-describe": "error", "lodash-fp/no-unused-result": "off", "unicorn/consistent-function-scoping": "off" } }, { "files": ["**/*.d.ts"], "plugins": ["@typescript-eslint"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": [ "./tsconfig.json", "./@types/tsconfig.json", "./packages/*/tsconfig.json" ] }, "rules": { "no-var": "off", "@typescript-eslint/consistent-type-definitions": [ "error", "interface" ], "@typescript-eslint/consistent-type-imports": [ "error", { "disallowTypeAnnotations": false, "fixStyle": "inline-type-imports" } ], "@typescript-eslint/no-explicit-any": "off", "import/no-extraneous-dependencies": "off" } }, { "files": ["**/*"], "extends": ["prettier"] } ] } ```
timostroehlein commented 6 days ago

I'm having the exact same issue in an Nx monorepo with the import/no-extraneous-dependencies rule

saiichihashimoto commented 6 days ago

@timostroehlein me too! I made an issue for that but, for whatever reason, it got marked as a duplicate of this one.

ljharb commented 6 days ago

@saiichihashimoto are they different issues? It read like they were the same.

saiichihashimoto commented 6 days ago

Maybe they come from the same problem, but they're two different eslint rules

timostroehlein commented 6 days ago

Yeah it's the same issue but for two different rules, so it might be caused by an underlying issue. I'm not using the import/no-unused-modules rule, so I can't say anything regarding that