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
Bug: no-restricted-exports
fails on export { default, ... } from ...
#15617
Comments
no-restricted-exports
fails on export { default, ... } from ...
This does look like a bug because, in this case, “default” is not a named export. @mdjermanovic do you agree? |
This works as intended, per the documentation for this rule on default exports: https://eslint.org/docs/rules/no-restricted-exports#default-exports An example of incorrect code in that section is basically the same as the example from the original post in regard to /*eslint no-restricted-exports: ["error", { "restrictedNamedExports": ["default"] }]*/
export { default } from "some_module"; Adding |
Thanks @mdjermanovic and @nzakas! Sorry, I am admittedly quite new to this
Thoughts @ljharb? (as you initially suggested this was an upstream fix in airbnb/javascript#2500 (comment)) EDIT: Ah seeing both you and ljharb were involved in the initial rule this came in on, so I'll just listen:
|
The original intention for the rule didn’t consider this, because default really isn’t a named export, conceptually - it’s just unfortunately implemented and specified as one. I think that if “default” is restricted, then it should apply to default exports whether named or not. If it doesn’t apply to both, it shouldn’t apply to either. |
@patcon can you please clarify the expected behavior of this rule with your configuration? In particular, if the intent is not to disallow |
We had the following options on how should the rule behave when it's configured with
This was discussed in #12546, and we eventually decided on 2. as that seemed the most flexible. The behavior is, I believe, well-documented in the Default Exports section. We didn't implement an option to disallow
|
@mdjermanovic i think that's fine for |
Ah, ok! In that case, if there's a need to disallow only specific ways to export {
"no-restricted-syntax": ["error",
// export default foo;
"ExportDefaultDeclaration",
// export { foo as default };
"ExportNamedDeclaration[source=null] > ExportSpecifier > :matches(Identifier[name='default'], Literal[value='default']).exported",
// export { default } from "mod"; export { foo as default } from "mod";
"ExportNamedDeclaration[source] > ExportSpecifier > :matches(Identifier[name='default'], Literal[value='default']).exported",
// export * as default from "mod";
"ExportAllDeclaration > :matches(Identifier[name='default'], Literal[value='default']).exported"
]
} |
@mdjermanovic Though I suspect maybe the convo has moved past this question: that choice comes from airbnb's rules, and I have no specific expectations (other than that something so highly used must know more than me 🙂 ) |
Airbnb's intention was to force default exports to use Using no-restricted-syntax, as always, isn't a viable option for a shared config because it's a) used for many things, and is hard to disable for just one of the items; and b) it doesn't convey meaning/intent the way a dedicated rule does. |
Since the current behavior is intentional and the rule works as documented, changing this would be a breaking change. Some users might be relying on this rule in combination with If we are going to make a breaking change, I think we should either include |
Could it be an option? |
An option seems like the fastest way to a solution. @mdjermanovic ? |
@ljharb which of the following would you like to disallow?
The current behavior with |
The Airbnb config strongly pushes default export usage, so we’d want to disallow only number 3 (and i guess 5, but that’s less important). 2 and 4 are valid re-export forms of the preferred export method, 1. |
Isn't 3. |
ohhh right, sorry, i confused myself. We do want to allow option 3 :-) so looking again, we want to prohibit 2 (and maybe 5), but 1 is ideal, and 3 and 4 are the only ways to do that, so they'd also be allowed. |
Okay, here are some ideas. a) Add a boolean option to re-allow 3 and 4. The option can be specified only if {
"no-restricted-exports": ["error", {
restrictedNamedExports: [
"then",
"default" // disallows 2, 3, 4, 5
],
allowDefaultFrom: true // re-allows 3 and 4
}]
} b) Add an object option with boolean properties for each 1-5. The option can be specified only if {
"no-restricted-exports": ["error", {
restrictedNamedExports: [
"then"
// no "default" here
],
restrictDefaultExports: {
direct: false, // 1. export default foo; export default 42; export default function foo() {}
named: true, // 2. export { foo as default };
defaultFrom: false, // 3. export { default } from "mod"; export { default as default } from "mod";
namedFrom: false, // 4. export { foo as default } from "mod";
namespaceFrom: true // 5. export * as default from "mod"
}
}]
} The b) is a bit more work but provides more than a), and I think it's easier to understand. I'd vote for b). |
Either would work for me, but i agree b is clearer and preferred. |
I agree that the second option is clearer. |
It seems that we have agreed to fix this problem by implementing option b) from #15617 (comment), so I marked this as accepted. @patcon would you like to submit a PR for the new option? |
@mdjermanovic I'd love to take a swing at it :) Sorry for not stepping up earlier -- the conversation felt a little beyond my ability to weigh in, but happy to try to make my first contrib here 🙂 Any pointers to specific areas of docs/codebase related to this, or that might be similar? (aside from things I'd learn in general docs, which I'm sure I can navigate on my own without taking your time) |
(and pls feel welcome to assign me so that it stays in my dashboard) |
The rule docs page is a good place to start: |
@patcon |
Hi @amareshsm are you still working on this? |
Any update on this ? This issue is still there. |
@shirshendubhowmick There is an open PR for this - #16785. It will be fixed soon. |
Environment
Node version: v14.18.1
npm version: v8.3.0
Local ESLint version: v8.9.0 (Currently used)
Global ESLint version: Not found
Operating System: darwin 20.6.0
What parser are you using?
Default (Espree)
What did you do?
Minimal reproduction repo here: https://github.com/patcon/eslint-bug-reproduction-default-export
What did you expect to happen?
Expected
npm run lint
to pass, sinceis just an alternative format, recommended in Mozilla web MDN docs :)
What actually happened?
Both forms of this default failed:
Participation
Additional comments
Re-ticketed from airbnb/javascript#2500
Thanks a bunch! Open to pointers in the right direction, or just affirmation that this is a bug 🎉 🐛
The text was updated successfully, but these errors were encountered: