-
-
Notifications
You must be signed in to change notification settings - Fork 9
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
Replace "loose" options with a top-level "assumptions" object #5
Replace "loose" options with a top-level "assumptions" object #5
Conversation
Love the visibility this brings into what "loose" was actually doing. Some questions
Naming bikeshedding thoughtsI wondered if it might be helpful to have a consistent "[feature] with [caveat]" nomenclature:
|
Fantastic work on compiling all the current options! re: Open Question:
re: option name 🚲 🏠 ing, I actually love @developit's proposed scheme! |
Would be equivalent to The list will most likely grow, and it is already large, I think we may need to remind people that again you can share this in an object, or a config somewhere. Probably may even write code comments to explain the options. for Agreed on naming, ideally feature name is similar to plugin name? Here's a related issue/PR regarding plugin options twbs/bootstrap#31011 |
Thanks y'all for taking the time to read this!
I would prefer not to do it, for two main reasons:
I initially thought about something like this: "assumptions": {
"templates": { "usePlus": true, "noFrozenObject": true }
} However, I now think that a flat list of options is easier to manage and to document. Also, it would create a new problem: should we deep-merge We could still have conceptual groups by starting the name of related with the same word, like
I'd say that if we can be sure that it can be optimized, we should do it even if the assumption is set to false (e.g.
I like this idea! I personally don't like your proposed option names because I found them not descriptive (sorry 😅): templates are always string, spread always introduces properties, arrows are always converted to functions, etc. However, I will see if I can rename the options following this pattern. @existentialism I'll reply to your points tomorrow! |
That PR will let us pass a full list to plugins. It's impossible to pass the final assumptions to presets if we allow presets to enable assumptions.
I initially wasn't 100% on board with it because it means that if we add support for a new assumptions in a plugin, then the user would need to update
Could you give an example of a possible conflict? 🙏 |
Co-authored-by: Brian Ng <[email protected]>
I tried using @developit's proposed naming scheme, but while some of those names are better than what I proposed, they are not always descriptive. While "doing some research", I actually understood what loose mode does and I think I have names that better describe not Babel's loose output, but the behavior of that output.
Templates always generate strings, and var o = { [Symbol.toPrimitive]: h => h };
`hint: ${o}` === "hint: string";
"hint: ".concat(o) === "hint: string"; // correct
"hint: " + o; === "hint: default"; // wrong (loose mode) Maybe
I propose (obj => {
"use strict";
obj.x = 2; // in loose mode, this doesn't throw
})``;
Here the key is that in loose mode we use // This should be 2, but it's 3 in loose mode
({ set x(v) { this.y = 3 }, get x() { return this.y }, ...{ x: 2 } }).x;
The difference in loose mode is that Object.getOwnPropertyNames(new class A { #x }) === ["__private_0_x"]
👍
I prefer to keep // input (main.js)
import * as mod from "./mod.js";
console.log(Object.keys(mod));
// input (mod.js)
export {};
// output (mod.js - spec)
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
// output (mod.js - loose)
"use strict";
exports.__esModule = true; In loose mode it logs
No strong preference here, both seem equally good/bad to me
Technically arrows are functions 😛 Maybe |
rfcs/0000-top-level-assumptions.md
Outdated
|
||
```typescript | ||
type Assumptions = { | ||
[assumption: string]: boolean |
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.
Are the default values of any assumption is false
? The newableArrowFunctions
can be a footgun since the assumption is more spec-compliant. Maybe we can have noNewableArrowFunctions
and make it defaults to true
?
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.
My plan for this is to default to true
for compat in Babel 7, and default to false
in Babel 8 (since currently it's the only thing where spec compliancy is opt-in)
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.
We can also consider deprecate spec
of preset-env
/transform-arrow-functions
and encourage to use assumptions
, so we can eventually remove spec
in Babel 8.
rfcs/0000-top-level-assumptions.md
Outdated
## Configuration merging | ||
|
||
Multiple `"assumptions"` objects should be merged using `Object.assign`, and not overwritten like other options. | ||
This makes it easy, for example, to enable one additional assumption for a specific folder. Also, it still keeps the ability of disabling an assumption simply by setting it to `false`. |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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.
Added to the RFC text
rfcs/0000-top-level-assumptions.md
Outdated
|
||
```typescript | ||
type Assumptions = { | ||
[assumption: string]: boolean |
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.
Another question: would assumptions allow options? If so merging assumptions
will be challenging.
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.
Yeah I described them as simple booleans exactly to avoid thinking about merging them 😅
I feel like we can just use longer names instead of nesting objects.
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.
Maybe I am too permissive, but think about how ESLint rules config starts from { [string]: boolean }
and end with { [string]: [number, object] }
. 😂 We will see.
rfcs/0000-top-level-assumptions.md
Outdated
|
||
- This RFC introduces a very big number of new top-level options (19), and makes it relatively cheap to add new ones. Having a big number of options can add more "tooling fatigue" on the shoulders of our users, and it can make it hard for us to properly document them. However, these new options replace 22 existing plugin options, many of which have the same name (`loose`) but different behaviors. | ||
|
||
- ([@JLHwung](https://github.com/JLHwung)) Some `assumptions` are only effective in one plugin, but users will have to go through their presets/plugins to see if they have opt-in to this plugins. Let's say there is an assumption in a stage-1 proposal and the users does not know it is no-op for their config, it may inadvertently turn into a long list of `assumptions` and the no-op assumptions can kick in once users upgrades `preset-env` which may includes it once its stage advances. |
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.
On possible assumptions in early stage plugins, can we limit assumptions
to be a something that related to stage 3 features or standard spec only? So we don't add assumptions about stage-1 plugins until they are mature enough. The assumptions can still be a valid plugin-specific optionl.
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 99%* agree! Maybe we should have the same policy we have for shippedProposals
?
* only 99% because, for example, the #foo in obj
transform is obviously influenced by the assumptions we make when transforming private fields (privateFieldsAsPublic
).
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.
In your case privateFieldsAsPublic
falls to shipped feature assumptions. A stage-1 proposal implementation can choose to respect such assumptions, but it can not, i.e. register a global privateInNeverNested
assumption, until it is mature enough -- So other plugins might have to take care of that.
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.
100% agree now 😄
I'll add a "Policy" section.
Co-authored-by: Huáng Jùnliàng <[email protected]>
rfcs/0000-top-level-assumptions.md
Outdated
- The option name | ||
- It's description | ||
- An example (which could be interactive, using CodeSandbox) | ||
- The affected plugins |
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.
Maybe worthy to offer a green engines list for each assumptions. Like if you are not transpiling down to these browsers, this assumption is a no-op for you. i.e. People should not worry about what is setSpreadProperties
if they are not traspiling object spread anyway.
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.
We could even automatically generate it by computing the union of all the affected plugins' targets maybe
rfcs/0000-top-level-assumptions.md
Outdated
# Open questions | ||
|
||
- Should we try to pass to the presets at least a _partial_ `assumptions` object? Currently `@babel/preset-env` relies on `loose` to enable/disable the `typeof-symbol` plugin. | ||
- Should we validate the list of `assumptions` in `@babel/core`, and disallow unknown ones? This would make it impossible for third-party plugins to introduce their own assumptions, but it also means that it's easier for us to introduce new assumptions without risking ecosystem incompatibilities. |
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.
#5 (comment) (@existentialism)
- My gut/initial reaction is that we should validate the list of
assumptions
#5 (comment) (@nicolo-ribaudo)
I initially wasn't 100% on board with it because it means that if we add support for a new assumptions in a plugin, then the user would need to update
@babel/core
in order to use it (otherwise Babel would throw an "unknown assumption" error).
However, I think that the benefits of validating outweigh this downside 👍
I was going to write in the RFC text that @babel/core
will throw on unknown assumptions, but I realized that if we add a new assumptions in @babel/[email protected]
, presets cannot use it because it would be a breaking change when used with @babel/[email protected]
.
Note that this problem will likely never affect our own presets (since we won't enable assumptions in our own presets), but it could affect framework-specific ones.
We have a few options:
- Decide that it's ok, presets can check Babel's version and conditionally enable an assumption.
- Only throw for unknown assumption in config files, not in presets.
- Throw in config files, warn in presets.
- Always warn.
- Don't validate the assumptions list.
In any case, we shouldn't pass unknown assumptions down to plugins.
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.
Agreed. Note that @babel/preset-env
also validate unknown options. If a preset depends on @babel/preset-env
, every time when a new option is introduced, they have to bump dependencies, too. I think it applies to assumptions
of @babel/core
, too.
View Rendered Text
These are the issues mentioned in the RFC. I'm putting them here so that GitHub links them.
babel/babel#11622 babel/babel#11248 babel/babel#6978 babel/babel#11689 babel/babel#11634