-
-
Notifications
You must be signed in to change notification settings - Fork 2
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
Adopt ES2015+ features in Unified collective #4
Conversation
related but not required by this. |
Controversial opinion™: ES6- is also ES6+. 😅 I think i’m in the minority with my personal opinions on these matters: All these new features are different, which is fine, but that doesn’t make them inherently better, nor worse. In some cases they are great! Async/await is really nice. Arrow functions are great for “lambdas”. Etcetera. To summarize, I don’t have anything against ES2015+ features, but I have problems with “Adopt ES2015+”:
These problems are fine in build scripts, it works well for a compiler like MDX, it’s a good decision if you’re building an app on top of unified. I think it works well in those cases because then it’s the end product: you’re in control. Often those things don’t last very long (a web app is rewritten from jquery -> backbone -> angular -> react -> X every Y years), in comparison to something like TL;DR: Change is not good in and of itself. So then the question is: what will this solve! What will this help? You point out:
(I’m one of the people that chose those options too btw 😉) But, what is the percentage of people that used What you sent me in DMs is interesting!:
Prototypes aren’t great, true… I’m guessing that those people know
The rules in [3] (ESLint) catch new problems that are introduced by ES2015+ features, but the also don’t inherently make the current code better?
Why do you think this improves maintainability?
We’re currently in a state where some our our (dev) dependencies are dropping support as well. This annoys me because it forces us to update too, and publish a major release, on that dependency’s schedule. Even if we’d set a unified policy to support Node X to Y, if our dependencies move faster, we can’t update, leading to potential security problems. Now I really don’t care about Rhino or IE10 or so, but there’s no harm in supporting a bit more that the current LTS either... P.S. one thing I’m pretty excited about is ESM!. |
Thanks for the feedback @wooorm! 🙇♂️
TL;DR: I agree. I'm not saying all ES2015- is bad, or that all ES2015+ is good. Also note that this is not all or nothing, we can adopt parts of the recommendation from the RFC without needing to adopt all of them, and the parts adopted could be staggered over time if wanted.
I'm looking at it from the perspective of "where are new contributors coming from?". A common theme through these, they are primarily front end and they are primarily related to React. It is important to note that these are not React specific, these are JavaScript language features. And while JavaScript doesn't remove features, there is a tendency to use a subset of the language "the good parts" which evolves over time.
I haven't seen this as much.
To offer a different perspective.
I see these two as somewhat going together.
How is that different than from today? If it's in a dev dependency, it isn't a breaking change for our adopters, and way may need to remove some checks on CI (annoying), but no impact downstream.
A different perspective. |
Seems like almost all arguments have been brought up already. Just adding my two cents.
|
Would there be interest in another RFC to discuss ESM? |
To me, this discussion when only posed (due to my comments) as “ES2015+ or ES2015-” leans towards yak-shaving (as in, lots of discussion about not very meaningful changes). Though we all seems to agree that we don’t want that to be the topic. We do seem to agree that some ES2015+ features, notably ESM, would be good (albeit uncertain about how and when, also due to my comments). I believe that ESM is a fruitful conversation to have because it’s more tangible: at least to me, I can scope what the changes would mean to the 300+ projects. Deciding on ESM (and when) would lead to deciding on minimum runtime versions, then opening the doors towards refactoring into things such as classes, and thus practically implementing/solving this RFC. Does that match how you all see this conversation? |
To be clear, this PR is labelled as "collective" because it would touch projects in several orgs.
I agree that ESM could be a lead in for refactors across the ecosystem. Native ESM with no CJS fallback may also require some testing with bundlers for browser usage, we'd need to do some research into how widely It may be worth it for ESM to have it's own RFC to discuss. |
I feel with ES2015+ features, ESM, and potentially officially supported Node versions the scope of this RFC will become too big. Unfortunately they aren’t mutually exclusive either. I think it makes sense to discuss ESM in a different RFC, as @ChristianMurphy mentioned, it requires research on its own. Choosing whether to adopt ES2015+ features in general shouldn’t stand in the way of the ESM RFC, we can always decide later if applying the decisions from the RFCs can be combined. Back to the intention of this PR. I mentioned before that I was more interested in allowing ES2015+ features instead of changing it throughout the ecosystem. But after thinking about it a bit more, I think it should be more about the latter. As choosing what makes sense for new projects is only natural and perhaps doesn’t need an RFC. Look at micromark, for instance, with its classes, generators, and TypeScript. So perhaps to make this RFC pass (or not) the focus should be on what, where, and why ES2015+ features would be an improvement.
@ChristianMurphy could you elaborate on what ES2015+ features these projects would benefit from and why? |
Most of these repos are, or include a constructor pattern. The other feature that could help a lot would be |
Definitely agree with the
Correct me if I’m wrong but this sounds like an implementation problem rather than To conclude, my personal preference would be in accepting this RFC for the bigger projects, like the examples @ChristianMurphy gave, with some ES2015+ that benefit matching syntax with intend, or help author better types. I don’t see a lot of benefit in also changing the utilities or other areas (for now). |
No even an implementation problem per se. |
For the classes/prototype: I’d prefer to move away from them entirely, where possible 😅
I’m up for doing this (depending on the ES feature)! Indeed, as @Murderlon points out, for the projects that fluctuate more that the lowest-level utilities; to do it for the projects that benefit from it. But I would like to do it together with a supported environments policy. It’s a breaking change. And I would prefer to combine it with other breaking changes. |
To kickstart this again: I am, perhaps more so now than in the previous comments, appalled by the state of the JavaScript ecosystem, which I feel originates in part because of an unhealthy appreciated for new syntactic sugar and the latest and greatest build tools. While these features or these tools are not bad on their own per se, the JavaScript ecosystem as a whole is in a bad state. I think we (@ChristianMurphy, @Murderlon, I) can agree that we have all seen many issues stemming from these tools and features. I would want to restart this problem not from a perspective of what features can we use, but rather: how can we be a part of a faster, safer, stabler, more maintainable, and also future proof ecosystem. What does that mean? What will ESM bring? How do we provide both cjs and mjs? How do we support Node and Browsers. Can we make sure that folks who compile their code, get the latest features, whereas folks who don’t compile, get stuff that works in most browsers? |
How so? You've expressed concerns around module types in the past, but not specifically with syntax itself.
All the features in the RFC are natively supported in Node and in most browsers.
@wooorm I think you're starting a new discussion, unrelated to this RFC, this RFC intentionally does not include ESM, as the different module types JavaScript supports are a complex and multifaceted topic. |
That is mostly correct: because while I agree that the points in Motivation are worthwhile, I don’t feel strongly that Detailed design solves them, whereas the Drawbacks are real. Specifically, for the detailed design, I believe
(All these features are nice on their own, especially in apps/scripts, etc, the questions is though: is it worth rewriting things, and if so: how exactly) I am fine with these changes, but two more downsides:
I think to reach the points in Motivation, we need more, such as:
These could be different RFCs, but I feel those ideas touch on this RFC, and they give this RFC more power. |
On the topic of ESM, https://github.com/mikeal/limbo may be a good option for adding support in a non-breaking way. |
@TrySound you mentioned on Twitter that you might have ideas on how to do ESM for micromark? Pinging you here to discuss more of that, if you’re interested! |
Converting to esm is easy. I did it locally with a few replace-in-files commands for micromark. Distribution will include main, module for bundlers and exports fields for node. Default export in entry points should be replaced with named one to prevent issues with ts definitions. |
Nice! Are you saying that there is no way to use default exports at all? We currently use TS definitions in several projects with CJS “defaults exports”. What is TypeScript’s problem with default exports? While micromark is new and it’s expected that stuff’ll break now, we are also approaching a point where the hundreds of projects in the unified collective move to ESM. It would be preferable if we can do that without breaking anything. |
This describes the issue |
Interesting read, thanks. In short, that seems to indicate that both a default, and a named export, are used. In .cjs: Object.defineProperty(exports, '__esModule', { value: true });
// ...
exports.default = memoizeOne;
exports.memoizeOne = memoizeOne; And .mjs: export default memoizeOne;
export { memoizeOne }; And .d.ts: export default memoizeOne;
export { memoizeOne }; |
Now yes, but it's mostly migration path. Ideally to use only named exports. |
One path forward with ESM is being discussed at micromark/micromark#27 |
Closes GH-27. Related to unifiedjs/rfcs#4. Reviewed-by: Christian Murphy <[email protected]> Reviewed-by: Titus Wormer <[email protected]>
* Add tests for local babel plugins * Replace babel w/ rollup * Remove unused constant Related-to unifiedjs/rfcs#4. Related-to GH-27. Related-to GH-28. Closes GH-35. Reviewed-by: Titus Wormer <[email protected]>
ESM and a limited set of ES6 features rolled out to most of unified as part of unifiedjs/unified#121 |
view rendered rfc: https://github.com/unifiedjs/rfcs/blob/877faea70af49b4e02134c4ad7483118026dd364/text/0000-javascript-2015-2019.md