-
-
Notifications
You must be signed in to change notification settings - Fork 5.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
6.0 #2168
Comments
This all sounds ace! it would be cool to bake-in per-plugin perf profiling from the start, so slow plugins can be identified & optimised/disabled. |
I am sad to see this direction (no more easy transformations by default), probably because I was doing the same with cssnext, but at the same time I totally understand the "Why". |
@MoOx I've thought about how to make it the easiest and the current solution is basically what I landed on. All that will be required to get 5.x behaviour is having the following {
"plugins": ["preset-es2015"]
} (Preset might be called something different but you get the point) @glenjamin Oh that'd definently be cool. |
You shouldn't require extra configuration just to get Babel's bread and butter (ES transpilation). I understand your vision for Babel, and it's great, but please keep it simple for the common use-case. All the future-future stuff sounds super exciting! |
@sebmck Yeah that's why said I like the approach. Thanks for your awesome work. Good direction. |
@brianblakely Trying to keep it as simple as possible but keeping any transforms enabled by default isn't very proactive. |
Forgot to mention that I'm also putting a feature freeze on 5.x |
You could have a generator/cli as the primary method for installation, so that doing babel-cli es2015 Would |
Having a preset for every subsequent version of ES (2015, 2016, etc) could get confusing to manage in a couple years. Perhaps it would be more enabling to relegate that stuff to an "esnext" preset instead, which makes Babel work for users the way it does today. Then you just update the preset on NPM and never need to touch your RC again. |
@brianblakely In the next couple of years people are going to be targetting completely different things depending on their requirements. Having a blanket version doesn't really work, especially when ES versions aren't going to mean anything anymore. |
I think the majority are still going to want to work with the latest ES features. Installing language features a la carte or looking up which preset to install is not a great experience for those users or their teams. Babel is just one tool of many, and should strive to be as zero-config as possible. |
Do you not think making Babel much much more powerful is a worthy tradeoff for literally 1 line of config? |
I don't believe this is true at all. The current babel users I would expect are largely made up of early adopters and those who happen to be in the same teams / on the same projects as early adopters. Using experimental babel features is not dissimilar to using coffee-script, it's a reasonable choice, but not one that the mainstream will definitely latch on to. |
I was thinking like you @brianblakely (I speak as the creator of "cssnext"), but I have to admit that handling the evolution of specs can be a pain, and can easily become a dangerous game (it's even harder for CSS because specs are exploded as different modules...). |
gif* :( In all seriousness, future looks great! Looking forward to these changes. |
As another data-point, another popular JS tool with a large set of configuration options recently switched to off-by-default - and survived. |
Nailed it well done 👍👍👍👍 |
@glenjamin everything off !== everything out ;) |
Yeah, JSCS has always had no options set by default; some wanted a certain preset (airbnb) to be default for 2.0.0 but didn't get enough support. |
In the last year I've been the early adopter teaching ES6 to non-early teams via Babel. ESLint's |
I want to cut off this discussion about what should be included in Babel by default as it's not been productive so far. Babel is a compiler. At it's heart it is a system for building transforms that take JavaScript in and spit JavaScript back out, and in between it can run all sorts of really complex operations on JavaScript. Babel has a lot built into it for making this easy. There are many applications for a compiler: transpiling, minifying, linting, type checking, etc. it's a very useful tool to have in many contexts. So to assert that it should have some default behavior as the "common use case" is misguided. Yes, transpiling of ES-next features will always be a supported by the Babel team, it's not necessarily the one it will be used for. Babel is meant for building an ES2015 transpiler (not being one), as well as many other tools. That's the use case Babel is going for and that's why this decision is being made. |
This sounds like a great direction. I agree with the sentiment of making the common case as easy as possible, but also strongly agree with documenting exactly what transforms a library requires. With the ability to put babel config into package.json, we end up neatly describing important characteristics of the source. |
This touches on something that I've been wanting to discuss. (Movie trailer voice) In a world where developers put non-compiled code on npm, do we want the ability to compile all of that down in Babel?* In other words, should a module bundler using Babel be able to require files that need different transforms based on the module being loaded? My understanding is that Browserify can do this via Should * Example use case: I wrote my library with a bunch of ES2015 features, rather than compile it forever I'm going to distribute the ES2015 version and have a |
+1000 for that, a really succinct way of putting it that explains this new direction. To me this sounds like a fantastic approach and one I'm really looking forward to working with. @thejameskyle I'd be really interested in being able to publish "raw" code rather than code that's been generated by Babel.
Not sure if Edit: you can use |
@jackfranklin You can specify your |
If you have to specify all the transformers you need then you might as well just specify them without the preset concept at all right? |
This approach, After some digging, the reasons for this seem to stem on npm and peer dependencies: docpad/docpad#927 (comment) I'm hoping the CLI would still be optional. |
@hzoo Nope. At first you will need to |
Oh ok you're saying the preset npm installs all of the transforms but you specify the ones you want |
Right. Wasn't it the purpose of the presets and I'm missing something? |
Why don't we use the following naming for packages?
It's easier to understand what's official and what's not. |
@teugen That was already bought up by @tgriesser here:
|
@sebmck peerDependencies will be deprecated in npm 3.0, so no point in taking that into consideration. I would really like to see more use of scoped packages in projects like babel which target a very large audience. Really like the roadmap, would be a lot easier to get involved in fixing bugs for specific plugins. First time I tried to wrap my head around babel's source was very overwhelming. |
I'm pretty sure this is no longer the case, peerDeps are staying, but will no longer auto-install, they'll just tell you what to add to your normal dependencies. |
It doesn't handle that. Per the
That's a contract? I don't have a solution to propose right now for presets, but I'm not enthused about a solution that requires a CLI. @sebmck @thejameskyle Since the subject of presets has so far dominated the discussion here, and there still seems to be a lot more to discuss, do you think it makes sense to try to direct future discussion to #1827? |
As long as the CLI and require hook both stay useful and easy to use I think these changes are all great. Keeping the code better abstracted for long term use is great but it shouldn't compromise the interface to the code for users. |
I like the idea behind rollup (Next-generation ES6 module bundler), would this be considered going forward? |
correct |
If this is what I think it is, I'm very excited for it. I'd love to be able to have the bundler / module formatters be able to use custom resolution algorithms(i.e. npm, bower, etc) and it sounds like this would enable that? |
awesome. 👍 😄 |
+1000. I ❤️ it! 👍 😄 |
peerDependencies have never been deprecated, it's always been just a case of the behaviour changing slightly. All it means is that if your plugins peer depend on babel, you will still need to install babel yourself. npm will warn that you are missing the dependency rather than installing it for you. |
Please refrain from 👍 it's hard enough already to filter through the babel/babel repo noise. |
Foreword: None of this is really set in stone. Feel free to argue and discuss. This is kinda a long issue so I added some gifs, I hear developers love that kind of stuff. This post is also a bit rough, figured it's better to get it out there ASAP, I'll improve it as more feedback is collected. Thanks everyone for your (potential) participation!
What is 6.0 going to look like?
No internal transformers. None. Zero. Zilch.
This will be coupled with the removal of the following options:
whitelist
blacklist
optional
loose
stage
All of these options are redundant when you're manually specifying transformers.
This dramatically reduces complexity in the transformer options. Right now there's way too many ways to change the state of a transformer. This will reduce friction and make it easier to reason about what's actually enabled.
There's also a major problem with including very experimental syntax/transformers in core. If a big change was made to their semantics it would be a breaking change and would require a major version bump of Babel. In the interest of stability and being reactive to changes in the standardisation process, it makes sense to version them independently.
When?
idk whenever
Where will all the current builtin transformers go?
Into userland plugins.
Wont this make it harder to use 6.x like we use 5.x?
Nope! 6.0 will also introduce the concept of presets. These are modules distributed via npm that specify a set of options (plugins etc) that will be merged into your main configuration.
Recommended
This means that the current ES6 to ES5 configuration would be distributed on npm via the
babel-preset-es2015
package. It would have theindex.js
of:To use this you'd just specify the following in your
.babelrc
:Community-specific
These can be even more specific. For example, the React community may have an official preset called
babel-preset-react
that will have the followingindex.js
:Just like the
es2015
preset, this could be enabled with the following.babelrc
:Isn't this a dramatic shift in focus?
Nope, this is a part of the long term vision for Babel and everything has been leading up to this (cue dramatic music). I bought this up in #568 back in January where I said:
What about syntax extensions?
I'll be holding out on allowing arbitrary syntax extensions for the timebeing. If we're going to do them at all, we're going to do them right. No point half assing a very critical and fragile piece such as syntax extension.
But if there's no syntax extensions then how would existing transformer that enable special syntax work?
So, the syntax would be implemented in the Babel parser Babylon, the "syntax plugins" would just toggle some parser options via an API. So the actual parser code would still live in Babylon. It's a neat solution until we support syntax extensions properly.
What else is coming?
Plugin options (#1833)
Plugin options are something that sorely needed.
Specifying options
These can be specified via a multidimensional array. For example, say you have a
babel-plugin-pancakes
plugin, you could specify options to it like so:.babelrc
But how would you specify options for plugins defined in a preset? One possible way is to specify them in the options to a preset, so if you had a preset like:
node_modules/babel-preset-breakfast/index.js
Then you could specify the options for
babel-plugin-pancakes
like so:.babelrc
Accessing them from a plugin
Swappable parser
Add a
parser
option to allow use of another Babel AST compatible parser.Plugin hooks (#1485)
There's currently no good way to perform initialisation of a plugin. Currently you can use the
Program
visitor to kinda simulate this, but those callbacks are only called once the traversal has already started. The introduce of ainit
andpost
method to a Plugin will make this make nicer:Way to provide the entire dependency graph to Babel
Another thing that I want to provide is a way to give Babel your entire dependency graph. This will allow cross file transformations. It'll allow us to catch more bugs (such as importing something from another module that wasn't exported).
This also allows us to simplify code (thus making it more performant) with access to other files. For example, we can drop the module interop output if we know that a file imported is ES6.
Minification plugins
I believe we can do minification better (if not equivalent) as UglifyJS. With the potential type information available this has the potential to lead to huge wins. I've already written quite a few plugins already and I believe with some time investment and the help of community plugins we can have a kickass minification pipeline.
Optimisation plugins
Babel plugins put a lot of potential for optimisations on the table. These optimisations fall into two categories:
Unreliable transformations
These transformations modify JavaScript semantics, they're pretty dangerous and fairly irresponsible. If you're a small devshop or independent developer it's probably way too risky to do this but if you're a largish tech company then you can weigh the risks and it may come out in favor of doing these sorts of transforms. The engine can't infer these kind of changes, you have to tell it that you don't care.
Want to assume all function expressions are constant value types and hoist them? Do it via a plugin.
Want to turn all function expressions that don't use
this
orarguments
into arrow functions? Do it via a plugin. (Arrow functions are currently faster than normal functions in Firefox and likely all other browsers in the future)Want to manually inline functions, removing the overhead of adding a frame to the call stack, potentially improving perf even if the function has been JIT inlined? Do it via a plugin.
Want to lazy load modules, assuming that the order they're imported doesn't matter as they're side effect free? Do it via a plugin.
You can kinda see how these assumptions can lead to fairly large wins. You just have to decide whether or not it's a good idea to do them.
Reliable transformations
These are transformations that can be done with 100% confidence. These can be performed without possibly breaking any code. With Flow integration and access to the dependency graph a lot of code can be statically inferrable.
But don't engines already do these? Different engines do different things. Some optimisations are too heavy for JITs to do but we have a bit more leeway since we're preprocessing offline. We also potentially have access to more information than engines (type annotations) and so can do some smarter things.
Debugging
Better debugging information will be absolutley necessary as Babel grows in complexity. A particular useful feature for userland would the ability to tell exactly what transforms are breaking or slowing down your build will be critical in this modulrisation.
Performance
5.x performance has improved drastically since 4.x. It could be better though. Performance will never stop being an issue.
If there's one part of Babel that is quite slow due to the overhead of JavaScript, there's the potential to provide two implementations of it. A fast version implemented via a native module that's used in Node and a pure JavaScript one that can be used in the browser. If parts of Babel get implemented as native modules there will always be a pure JavaScript version available.
See issue #1486 for related performance discussion.
Async API
Why?
This will allow an RPC with a long running server such as Flow. This will allow access to a large amount of type info. This will also allow IO to be done.
What about integrations that only allow a synchronous API?
A synchronous API will still be available for those limited integrations. If you attempt to use the synchronous API with plugins that have async visitors then an error will be thrown. Most of the systems that Babel has to integrate with are already async so this shouldn't be a concern for 90% of developers.
Anything else?
Probably forgetting something, I'll add more to this issue as I remember and feedback is collected.
cc everyone
The text was updated successfully, but these errors were encountered: