Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eslint-config-next should support absolute imports #25920

Closed
stefanprobst opened this issue Jun 9, 2021 · 9 comments
Closed

eslint-config-next should support absolute imports #25920

stefanprobst opened this issue Jun 9, 2021 · 9 comments
Assignees
Labels
bug Issue was opened via the bug report template.

Comments

@stefanprobst
Copy link
Contributor

What version of Next.js are you using?

10.2.4-canary.9

What version of Node.js are you using?

14

What browser are you using?

Firefox

What operating system are you using?

Ubuntu

How are you deploying your application?

n/a

Describe the Bug

eslint-config-next includes eslint-plugin-import with eslint-import-resolver-node, which does not support absolute imports (set via tsconfig.json#paths).

this is not an issue in the default next eslint config, because it only enables the no-anonymous-default-export rule, but becomes apparent as soon as a user extends plugin:import/recommended or adds any import-related rules from eslint-plugin-import.

possible solution would be to use eslint-import-resolver-typescript

Expected Behavior

default next eslint config should be set up to work with absolute imports (tsconfig paths)

To Reproduce

happy to provide a repro if necessary

@stefanprobst stefanprobst added the bug Issue was opened via the bug report template. label Jun 9, 2021
@housseindjirdeh housseindjirdeh self-assigned this Jun 10, 2021
@housseindjirdeh
Copy link
Collaborator

Thanks for logging this @stefanprobst

Just to clarify, wouldn't this be possible by locally extending moduleDirectory in eslint-plugin-import's node module resolution plugin?

{
  "extends": ["react-app", "plugin:import/errors", "plugin:import/warnings"],
  "settings": {
    "import/resolver": {
      "node": {
        "moduleDirectory": ["node_modules", "src/"]
      }
    }
  }
}

Or would you prefer that Next.js supports this by default to match all absolute paths that are set within tsconfig.json?

@stefanprobst
Copy link
Contributor Author

stefanprobst commented Jun 17, 2021

hi @housseindjirdeh , thank you for all your work on eslint integration in next!

personally, i'd prefer to integrate with eslint-import-resolver-typescript for typescript projects by default.

here`s my "user story":

  • i create a new project with yarn create next-app issue-next-lint --typescript
  • and add the following to tsconfig.json#compilerOptions:
+ "baseUrl": ".",
+ "paths": {
+   "@/*": ["src/*"],
+   "~/*": ["*"]
+ }
  • i rename .eslintrc to .eslintrc.json (because eslint recommends being explicit about extensions)
  • i enable the following in .eslintrc.json:
- "extends": ["next", "next/core-web-vitals"]
+ "extends": ["plugin:import/recommended", "next", "next/core-web-vitals"]
  • i move pages and styles folder to src:
mkdir src && mv pages styles src
  • in src/pages/index.tsx i change the following:
import styles from '../styles/Home.module.css'
import styles from "@/styles/Home.module.css";
  • now running yarn lint gives the following error:
./src/pages/index.tsx
3:20  Error: Unable to resolve path to module '@/styles/Home.module.css'.  import/no-unresolved
  • ok, adding a custom moduleDirectory setting for eslint-plugin-import to .eslintrc.json:
{
  "extends": ["plugin:import/recommended", "next", "next/core-web-vitals"],
+ "settings": {
+   "import/resolver": {
+     "node": {
+       "moduleDirectory": ["node_modules", "src/"]
+     }
+   }
+ }
}
  • now running yarn lint - still throws the same error! huh?

  • aha! i cannot actually use import from '@/... because eslint-import-resovler-node's option moduleDirectory does not understand.

  • ok, change the import:

- import styles from "@/styles/Home.module.css";
+ import styles from "styles/Home.module.css";
  • run yarn lint again - it works!

  • now install a type-only package:

yarn add -D @types/unist
  • and import it in src/pages/index.tsx:
import type { Node } from "unist";
  • ok, this doesn't work:
4:27  Error: Unable to resolve path to module 'unist'.  import/no-unresolved
  • let's try this:
yarn add -D eslint-import-resolver-typescript
  • and revert the import back to @/styles/Home.module.css
  • and edit .eslintrc.json
"settings": {
  "import/resolver": {
-   "node": {
-      "moduleDirectory": ["node_modules", "src/"]
-    }
+   "typescript": {}
  }
}
  • try again - what? yarn lint still throws?

  • ok, cool, we can tell eslint-import-resolver-typescript about type-only imports (eslint-import-resolver-node knows nothing about these):

"import/resolver": {
  "typescript": {
+   "alwaysTryTypes": true
  }
}
  • now everything works as expected.

@housseindjirdeh
Copy link
Collaborator

hi @housseindjirdeh , thank you for all your work on eslint integration in next!

Thank you for all the amazing feedback. Have appreciated each and every one :)

Wow thank you so much for going into so much detail explaining the exact issue. Definitely see the concern of trying to wrangle with absolute imports defined in TS config. Just added eslint-import-resolver-typescript in this PR :)

@stefanprobst
Copy link
Contributor Author

nice! when setting both eslint-import-resolver-node and eslint-import-resolver-typescript, does the last one take precedence? (haven't checked myself yet)

@housseindjirdeh
Copy link
Collaborator

Looks like the first resolver that successfully resolves is always the source of truth per the docs.

Should eslint-import-resolver-typescript take precedence here?

@housseindjirdeh
Copy link
Collaborator

Also closing this in lieu of #26280, but can re-open if things still need to be tweaked 🙏

@stefanprobst
Copy link
Contributor Author

@housseindjirdeh

my only concern was a potentional perf impact, because for absolute imports now both resolvers will run (first node, which cannot find it, then typescript).

but i did a small unscientific benchmark (here), and it seems the impact is negligible - so 👍.

@housseindjirdeh
Copy link
Collaborator

Awesome, thanks for doing a quick perf test and for all the feedback mate :)

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests

3 participants