-
-
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
Add rule to enforce default import naming #1143
base: main
Are you sure you want to change the base?
Conversation
9ea1200
to
072305c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't quite what was discussed in #1041.
af337e7
to
db0623e
Compare
Updated ;) |
So I guess it is not gonna be accepted unless I make it conform to the propositions listed in the linked issue? |
How is this related to #1041? That issue seems to be about enforcing the same name a library uses to export its default with (e.g. |
db0623e
to
a138319
Compare
Any update on this? |
a138319
to
2b5dde9
Compare
Any update on this one? |
2b5dde9
to
11361eb
Compare
Updated. Let me know what you think. |
f0f7cef
to
7f2fcef
Compare
Let me know what you think now |
Any update on this? ;) |
7f2fcef
to
73969b6
Compare
62c11b4
to
0da6220
Compare
Updated once again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens with import * as Something from 'prop-types'
?
68a276f
to
56d9aaf
Compare
test({ | ||
code: `import {default as propTypes, foo} from 'prop-types';`, | ||
options: [{'prop-types': 'PropTypes'}], | ||
output: `import {default as PropTypes, foo} from 'prop-types';`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm a little concerned with making this autofixable, if you won't be updating all the other places ijn the file where this variable is referenced (and it might not be safe to update it, if it's used in something like const obj = { PropTypes };
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell this will update all the references apart from the exported identifiers. I am getting confused. Isn't it something that we agreed on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ljharb can you please elaborate on this comment since I think it does what you said.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we include test cases that have lots of references to the imported thing, so the autofix output can demonstrate that it updates too?
docs/rules/rename-default-import.md
Outdated
"rules": { | ||
"import/rename-default-import": [ | ||
"warn", { | ||
"prop-types": "PropTypes", // key: name of the module, value: desired binding for default import |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what validates that the RHS of this object is a valid JS identifier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment it is only the user of the plugin who should be aware what they are doing. I could do something like eval(`(() => {var ${mapping}})()`)
or new Function(`var ${mapping}`)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though it is not the safest way to check for this..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is checking that even important? sounds like a case of garbage-in, garbage-out if people put invalid stuff there...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer my projects not to ever emit garbage :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we decide to validate the user-provided identifier I would like to find out an easy way to do it. Because so far I couldn't find a simple and secure solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @mic4ael
Sorry for reincarnating this thread after such a long time. My take on this would be to parse either var ${mapping}
or ${mapping}
using espree
- a module also used internally by eslint
for parsing code.
In case of ${mapping}
:
https://astexplorer.net/#/gist/94e57078a7e95dbf910a262c645dd3ea/b82ba422cd8e946bee02a1209795a1bbaa9be225
The parsed AST should consist of exactly one ExpressionStatement
having an Identifier
set as its expression
. Everything else (or an exception) is treated as an incorrect mapping
.
In case of var ${mapping}
:
https://astexplorer.net/#/gist/40823431b92aaf01426b255e4ad7163f/24a943d0b759cdf8aff897dfa1c5dcba48cb3847
The parsed AST should consist of exactly one VariableDeclaration
, which has its init
set to null
and its id
set to an Identifier
.
That way you can be sure mapping
is no garbage.
This comment has been minimized.
This comment has been minimized.
56d9aaf
to
6a6b827
Compare
64e823f
to
6194ac0
Compare
6194ac0
to
f579ea7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I made a few tweaks and added a test case (which is unfortunately failing).
I'm not convinced on the rule name, though - rename-default-import
is a bit weird; this seems more like enforce-import-name
. It also kind of seems like the same rule should be preventing named imports from being renamed with as
?
f579ea7
to
126ad82
Compare
Ok, I will rename it and will look into the suggestion you made. |
Also, as to this:
Can you please provide an example of what exactly you mean by that? |
126ad82
to
f48590d
Compare
hey @ljharb, can you please take a quick look at my responses? I would like to clarify some of the issues and (maybe) finalize this PR. |
FWIW, I agree with @ljharb that the rule's name sounds like it might enforce any import name, not just the default, but I don't know that there is much value in the latter and I think the config could be made smarter if that enhancement is desired later, e.g.
Hard to argue with this 😅 since I'm generally MIA and @ljharb is a person dedicated to keeping it clean and understands the cost of adding code that you're not prepared to maintain, which I really appreciate. Also, there is always |
I just looked at this rule source code and it looks like it doesn't do at all what was described in the original #1041 feature request? It was supposed to enforce the name in the import statement, but it should go to the imported file and look at the export name and enforce that. Right now it only enforces the names which you define in the options and you have to manually list all the modules with default exports and also find out what are the names of these default exports. All this information is already available: for external packages it's in their I'm 100% sure it's possible to implement because VSCode can suggest autoimports based on the names of default exports in other files. Also I'm pretty sure that TSLint has a similar rule. |
Ah yep, good point @phaux. also @ThiefMaster and @ljharb before you, heh. 😅 I should have re-read the source issue before chiming in at the end. (also: I didn't read enough of the following discussion to know if I'm about to just restate discussion from there 😬) @mic4ael: is it important for your use that the rule config allow you to lint for a name that is not the original module's default export's name? Properly solving #1041 will necessitate the original module code is available but that is typically the expected case for this plugin, and the resolver sub-plugins implement that side of it anyway (e.g. the TS resolver plugin knows where to find Also consequently, if the default export is some nameless expression, this rule would not apply. Less config == better config, IMO. I'd be fine with allowing overrides if absolutely necessary, but not allowing them and just always reading the source for the default export's true name would be simpler. |
I don't think this is helpful... as a user of a library you have no influence on that. I don't know if e.g. |
Okay, so there is some desire to allow overrides then. That would support unnamed exports, false modules (e.g. CommonJS), and renaming. Still seems like you'd want the default behavior to pick up the module's original name if it's available, though? |
This rule enforces a specific naming for default imports.
Fixes #1041.
Closes indico/indico#3329