-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
import/order
fails to recognize internal import groups
#807
Comments
Also seeing this issue, even without the resolver plugin. Would love to see this fixed, or if there's something missing in the docs about how to configure it please let us know. |
Including one broken test related to the import-js#807
Including one broken test related to the import-js#807
I think what is missing is an option for custom resolver to define to which group a resolved file belongs to. |
@lo1tuma Sorry if this is a dumb question but where would I add that? |
@Whoaa512 AFAIK that’s not yet implemented in |
Right, I was asking were I to contribute to |
The root cause of the issue seems to be the fact that the import type of a path like |
How does node handle that? ~ as the user's home dir isn't exactly a cross-platform thing. |
Edit: Actually that proposed solution doesn't solve the issue so please ignore tl;dr: Can we change @ljharb, Node handles the This issue deals with the fact that the OP has configured his babel setup to replace instances of Now I think the discussion needs to take a turn since we've come to the cause of the issue, as noted by @yenbekbay (#807 (comment)). Basically can we change the regex for determining if import name is an external module, from I would propose changing it to |
What about absolute paths? |
Maybe the actual fix is just to allow a setting which gives flexibility to what is considered an internal module. Maybe something like this: function isInternalModule(name, settings, path) {
const folders = settings && settings['import/internal-module-folders']
const customInternalModule = folders && folders.some(folder => name.startsWith(folder))
return customInternalModule || externalModuleRegExp.test(name) && !isExternalPath(path, name, settings)
} |
Any resolution on this? I just ran into the same issue. it won't even show warnings for me with |
@Whoaa512 I can give it a shot this weekend. |
FYI, my use-case is a yarn workspace with namespaced packages. When using import/order, all my actually internal packages are treated as external, and it would be great to have some control over that treatment. |
Hi, I just ran into a similar issue in our Angular project. My rule is configured as the following:
Code raising an issue:
If I remove Maybe there should be a way to tell ESlint how to recognize an internal module. Is there a way to fix it or contribute? |
@dgrishajev Feel free to pick up the PR #914, I'll add you as a collaborator on my fork. So you can update the branch related to that PR. |
Maybe a bit off topic but.. Can't we just configure certain top-level paths to be explicitly treated as internal, like |
@Whoaa512 Thanks, I'll do some research in the next few weeks. |
@loopmode If you wish to use a config to specify top-level internal modules you can use my fork: @fictiv/eslint-plugin-import Then in your settings in your settings:
import/internal-module-folders: ['shared/', '@client/'] |
Is there any work happening on this topic? I could put some effort as I am experiencing this issue |
@Whoaa512 could you create a PR to add the fix here? |
@mrmckeb Already did but it was closed in favor of implementing a custom resolver option described here #807 (comment) Unfortunately I'm not able to work on this for the next month or so. Would love a fresh set of eyes to take a stab at it though. |
@Whoaa512 I could try to take a look on it. Could give some initial guidance/context? |
It might be nice to allow people to just set a list of modules that are internal as a workaround? @Whoaa512 that sounds good - @viniciusffj I'll be interested to see what you come up with! |
I saw that too @smdern - and I think it would do the trick, however I think the idea of layering resolvers to solve this is not ideal though... and a potential source of issues in future. |
@smdern : can you give an example of how that alias resolver fixes the issue, and how you would set it up? |
Yeah, I'd like to know that too. |
I was able to add the alias resolver, and it does seem to improve the behavior. In my case, I don't have specific aliases set up, but I do have "absolute imports" set up for a Create-React-App + TS project. My "include": [
"src"
] For my app specifically, the source folder structure is:
and so typical imports might look like: import {RootState} from "app/reducers/rootReducer";
import {showDialog} from "common/dialogs/dialogsRegistry";
import {logout} from "features/auth/authSlice"; Those are imports I would want classified as "internal". I added these settings to my ESLint config: "settings": {
"import/resolver": {
"typescript": {
"directory": "."
},
"alias": {
"map": [
["app", "./src/app"],
["common", "./src/common"],
["features", "./src/features"]
],
"extensions": [".ts", ".js", ".jsx", ".json"]
}
}
},
"rules": {
"import/order": [
"warn",
{
"groups": ["builtin", "external", "internal", "parent", "sibling", "index"],
"newlines-between": "always-and-inside-groups"
}
]
} That appears to have them mostly sorting how I want - after 3rd-party libs, and before local relative imports. |
I initially tried the typescript resolver, but it kept counting modules that were included via a If you're using Heres my config {
"compilerOptions": {
"paths": {
"src/*": ["src/*"]
}
}
}
const root = (...args) => path.resolve(__dirname, ...args)
{
settings: {
'import/resolver': {
alias: {
map: [['src', root('client/src')]],
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
},
},
},
},
} |
@smdern we face the same problem and just adding the setting with |
Hi there, I resolved this issue the following way. I hope this can help someone. For JavaScript:
And overrides for TypeScript files:
|
Is this a bug or expected behavior? After reading all these comments and the docs I'm still unclear how to get this plugin to separate external from internal imports. Why aren't files under /src considered internal by default? |
@ra50 relative types always parent or sibling; This is a long thread and I'm not clear on what's actionable here. What would help the most is a PR with failing test cases (and even better, also a fix! but i can handle that part) so it's clear what needs fixing. |
@ljharb I believe that missing distinction is what is actionable here: most of us are asking for a new feature and concept of local workspace packages vs registry-installed packages. It doesn't help that no such concept exists and is documented or not. In the end, from a project's codebase perspective this is a major distinction between "dependencies" and actual "source code". In modern projects with workspaces, you just can't tell the difference by looking at an imported package name, e.g. By the way, workspaces are not just a yarn feature anymore - npm 7 embraces and introduces the exact same concept of workspaces and local packages, see https://github.com/npm/rfcs/blob/latest/accepted/0026-workspaces.md So what's needed is a conceptual decision for the plugin first: support local packages and allow some control over the handling, or not. The implementation could be anything from a simple yet good solution where users configure the plugin and tell it "what is local", to more complex solutions that use the actual npm/yarn APIs and inherently know which packages are from local workspaces and which aren't. |
I think it would be quite reasonable, once npm 7 is finalized, to have an automatic import group derived from the "workspaces" field in package.json. Would that meet the use case? |
Unfortunately, I drove the discussion off-topic.. Workspaces are a different use case entirely. Totally worth supporting, but I don't see how that relates to the OP. Apologies. |
In that case, I'll repeat:
At this point, I'm going to close the thread, but will immediately reopen it once it becomes clear what the remaining issue is :-) |
@ljharb Thanks for the reply. I think the confusion here (at least for me) is that people might expect I understand that relative paths will always be
and explicitly specifying the import order using the I don't understand why this works though, and it'd be great if the plugin supported this use case out of the box or without such complicated configuration. |
I want to clarify the approach I highlighted above also worked within a monorepo, with a root ESLint config. However, for us, internal means inside a package, and that may be a distinction. We don't count other packages in the monorepo as internal. I used the On a new project I'm working on, which is not a monorepo, I just used the below and internal groups are working as expected: module.exports = {
extends: [
// ...
'plugin:import/typescript',
],
// ...
settings: {
'import/resolver': {
node: {
paths: 'src',
},
},
},
}; |
From the docs:
The description of "sibling" and "parent" also precludes anything from being left to be classified as "internal". Note that https://github.com/benmosher/eslint-plugin-import/blob/master/README.md#importinternal-regex can be used to force things to be treated as "internal". |
@ljharb Thanks. I guess that wasn't clear to me, that statement didn't seem to imply that
The solution I posted above solves my use case and treats any import within the monorepo as |
Including one broken test related to the import-js#807
Including one broken test related to the import-js#807
Including one broken test related to the import-js#807
I'm using babel-plugin-module-resolver with eslint-import-resolver-babel-module to map imports from
~/<path>
tosrc/<path>
:In my ESLint config, the
import/order
rule is turned on using the following configuration:Imports from
~/<path>
, I believe, should be classified as an internal import group separated from other groups by a newline. I'm not sure what the behaviour is here, but given the following code:I'm receiving the following error:
The text was updated successfully, but these errors were encountered: