
Babel 6 – useless by default - andrewstuart
http://fourlightyears.blogspot.com/2016/03/babel-6-useless-by-default-lesson-in.html
======
amasad
I'm on the Babel team and this decision was intentional. The purpose that
Babel serves now is more geared towards providing the building blocks to
create a JavaScript development experience rather than providing one. It's up
to Ember, React, React Native, or your favorite boilerplate, cli, etc to
create that nice getting started experience with healthy defaults. We either
do a shitty job trying to serve everyone and everything or we take a step back
and enable people more knowledgeable with their user needs to create those
experiences.

Babel < 6 was trying to be everything for everyone and that wasn't working
out. Everyone wanted to get their pet feature in. And we came under fire for
making it easy for people to use experimental features.

That said, there is probably room to create a es2015-cli or something like it
that provides a default experience, but that's orthogonal to this discussion.

Finally, the point you raise about Babel just disappearing into the stack is
also misinformed. Transpiling should always be a technical decision to be
made. For example, you should know that a for-of statement will transpile to
include a bunch of runtime checks that would be slow in hot code etc.

~~~
ihsw
How do you feel about Babel -- and, to a greater extent, ES6+ -- losing out to
TypeScript due to the difficulty in getting into it?

I use TS exclusively, and that is unrelated to working with it professionally
on a daily basis. It is a thorough pleasure.

------
loganfsmyth
I totally agree that the initial user experience for Babel could use some
work. We don't tend to do a great job of guiding users through initial setup.
It absolutely needs work. I'd be curious to hear the author's thoughts on what
we can do better in that respect, since "no config" probably isn't going to
happen off the bat.

On the other hand, I don't feel that it's reasonable to assume that setting up
a build system will be trivial. Jumping into ES6 isn't and shouldn't be a
trivial decision, transpilation is a complex process with edge cases. That
doesn't mean it should be a pain in the ass, and I don't want it to be, but it
doesn't mean it will be instantaneous and easy. Users have totally different
build targets (different Node versions, different browsers, some need IE8
support, some don't). Different systems need different levels of polyfilling
and differing output syntax.

Enabling everything by default is one option here, but that encourages people
to not consider how things actually work, which is rarely a good idea. It also
assumes that adding complexity around knowing what to _disable_ is actually
better, which I'm not convinced it is.

~~~
taion
Exactly! Enabling unstable language features like decorators by default is the
opposite of a novice-friendly decision, as is enabling by default features
that require pulling in e.g. the Regenerator runtime.

The author of the post doesn't seem to understand that many of the transforms
supported by Babel touch on proposals that are actually at various stages of
being experimental or unstable, which actively _should not_ be enabled by
default for the sanity of users who don't know better.

Opting a novice user by default into a language feature that might well change
is not a good thing! Otherwise we end up with something dumb like the legacy
decorator transform, where people unknowing code against proposals that are
liable to change under them.

Babel-5-stage-0-ese is not ES.next!

~~~
andrewstuart
>> actively should not be enabled by default for the sanity of users who don't
know better

The idea that users should be protected from themselves isn't an effective one
and is at the heart of the idea that Babel should do less and more should be
configured in.

Nothing terrible will happen if a user uses a feature that is experimental or
unstable. They might get to use it successfully however if it comes
preconfigured. I can just update my code when the spec stablises.

>> the sanity of users

The sanity of users is broken by the myriad problems with Babel configuration.

~~~
thejameskyle
It's not that the users should be protected from themselves, but that they
should be protected from instability.

Proposals are constantly changing, and keeping a monolithic Babel on track
with them without breaking things for users all the time is a difficult
problem.

The configuration is more than just configuration, it's explicitness. It's
telling Babel exactly what you want out of it. That way you never have to
worry about changing behavior until you want to make the migration.

The situation is more nuanced than you are recognizing.

~~~
andrewstuart
>> but that they should be protected from instability.

Appropriate protection is a warning in the docs "this code might change when
the spec is finalised".

Inappropriate protection is hiding those features away behind difficult-to-
configure barriers making it only possible for experts to configure their
systems to run it.

~~~
thejameskyle
We did have those warnings in the docs. I _wrote_ those warning. No one paid
any attention to them.

I hate to say it, but you really don't know what you are talking about.

~~~
dang
> _I hate to say it, but you really don 't know what you are talking about._

Please refrain from getting personal in arguments on HN, even though it's
frustrating when someone doesn't know what they're talking about.

This comment would be great with just the first paragraph.

------
taion
The author posits that "Babel should come pre configured with the kitchen sink
of JavaScript development - async await, decorators etc etc."

There's a very good reason that Babel doesn't, and we should actually be
fairly grateful that the Babel team have made the considered decision not to
include such things.

First off, neither async/await nor decorators are actually part of ES2015.
They're both TC39 proposals, at various stages of completion:
[https://github.com/tc39/ecma262](https://github.com/tc39/ecma262). Very
justifiably, neither Babel 5 nor Babel 6 transpiled those out-of-the-box by
default; for novice programmers, using language features that are unstable
proposals that have not finalized is quite dangerous – what are you going to
do if those proposals change, as the decorators proposal actually has changed?

More specifically, there are meaningful issues with both of those transforms
if used without further thought. Babel's stock transpilation of async/await
brings in an entire runtime component in the form of the Regenerator runtime,
and additionally requires that Promises exist in the JavaScript environment,
which requires polyfills in the general case.

For decorators, the proposal _itself_ is still in flux. The current version of
the proposal ([https://github.com/wycats/javascript-
decorators/blob/master/...](https://github.com/wycats/javascript-
decorators/blob/master/interop/reusability.md)) is actually quite different
from the old proposal, which was the one that was implemented in Babel 5.
Additionally, the current proposal isn't even fully nailed down yet. Certainly
one should not expect Babel to implement a language feature for which there
isn't even yet a stable proposal!

This isn't to say that Babel 6 is perfect, but the specific counterexamples
the author of this post brings up are extremely weak, and if anything
demonstrate very good choices on the part of the maintainers of Babel.

~~~
andrewstuart
>>what are you going to do if those proposals change, as the decorators
proposal actually has changed?

I'd just update my code to meet the spec. Likely it would take vastly less
time than the hours needed to fail in configuring Babel. The documentation can
just say "this feature isn't finalised, it might change." That's enough. The
code does not need to be disabled just because the spec isn't final.

>> quite dangerous

It's not really dangerous. No-one is going to die. It's emotive words like
dangerous that lead Babel developers to think "we'd better hide that
functionality behind hard-to-configure barriers so people don't cut themselves
on the dangerous code".

~~~
thejameskyle
It's extremely dangerous, we're talking about tens of thousands of developers
who have chosen to depend on Babel for their livelihood, we can't just keep
breaking things on them.

We don't want Babel's configuration to be difficult, we just want people to
explicitly tell us what they want.

If you have suggestions on how to make the configuration easier I'm happy to
hear it. But turning stuff on by default it a terrible terrible decision that
hurts the community.

------
zbyte64
I love babel6 but this article made me laugh. The tragedy of babel 6 is that
it used to be simple to introduce to newcomers, now I have to chain them to a
desk. Now excuse me while I cry myself to sleep over how many hours I wasted
configuring software.

------
ksherlock
I gave up on trying to use the babel 6 cli and wrote a global-happy
replacement[1]. It still doesn't do anything by default (well, other than
indent, add semi-colons, and check syntax) but typing `babel --es2015` is
easier than installing a few hundred megabytes of node modules and configuring
a .babelrc file just so it can convert `const` to `var`.

1: [https://github.com/ksherlock/better-babel-
cli](https://github.com/ksherlock/better-babel-cli)

1.1: [https://www.npmjs.com/package/better-babel-
cli](https://www.npmjs.com/package/better-babel-cli)

~~~
lobster_johnson
Indeed, I am concerned about the trend towards locally installed NPM modules,
away from globally installed ones. The other project exhibiting this trend is
ESLint. It used to work beautifully globally installed, then the developers
broke it; it's better now, but there are still some bugs. Having one ESLint
config per project and making it a direct dependency is ridiculous when you
have a dozen projects and all you want is in-editor linting (in Atom, in my
case).

~~~
kevinsimper
The problem is that you can't require global modules, so that global module
needs to have installed everything that needs, and if it needs to support
multiple projects with different requirements, that global modules needs a
whole lot of modules itself in its package.json, and now that global module is
unmaintainable, because of all its dependencies. That is why global modules is
generally not useful and that it is better to have them installed locally.

------
bschwindHN
You could just _not_ use Babel and ES6. It's actually pretty beginner-friendly
when you go that route. It's not like you'd be missing out on features that
you absolutely need to have to make an app or a backend.

~~~
dwaltrip
And your app will have non-trivially better performance.

[https://kpdecker.github.io/six-speed/](https://kpdecker.github.io/six-speed/)

------
Niksko
Gotta agree with the author here. Trying to wade into modern JS is really
really hard. There are sooooooo many different ways of doing things, and
tutorials written a few months ago can be out of date.

~~~
ihsw
It is for this reason that I will avoid JS like the plague, and instead opt
for TypeScript.

I have been satisfied so far.

~~~
Niksko
That's not really avoiding the problem. The problem isn't just figuring out
how to get all of your nice ES2015/2016 constructs to compile down to a format
that can be understood by browsers and node. It's also all of the libraries
that are in vogue and that you sort of need unless you're wanting to totally
reinvent the wheel.

------
ludamad
I heartily recommend TypeScript as an ES6 compiler with excellent support for
commenting types used.

~~~
andrewstuart
I note that
[https://jaxenter.com/typescript-1-7-122642.html](https://jaxenter.com/typescript-1-7-122642.html)
"TypeScript 1.7 is here with async/await as default for ES6" makes a point of
saying "as default". Nice to hear.

I'm now going to attempt to switch to TypeScript. I wonder how deep this new
rabbit hole will be.....

~~~
ludamad
Note 'for ES6'. This is a fairly large caveat, as it requires you to have a
way to deal with the emitted ES6 code. The problem being that TypeScript does
not currently down-emit generators. Strictly speaking, TypeScript provides
excellent down-emit support for a subset of ES6, and the rest of ES6 support
such as 'let' captured in closures and generators need another compiler to
down-emit the generated ES6 (for now).

~~~
WorldMaker
There's definitely still cases where you want some subset of Babel or CoreJS
polyfills AND Typescript.

The magic may be in Typescript helping you figure out which runtime polyfills
to configure, maybe even spit out something resembling a .babelrc for your
Typescript project.

There's definitely discussions on this topic in the GitHub Issues, though I
haven't perused them recently so I can't tell you right now if there is any
progress.

------
chipsy
After a certain point, it's better for a system to be absorbed into an API
instead of trying to be configurable. Then you can just write code again, and
it's complex but not idiosyncratic.

------
msoad
I use TypeScript compiler for transpiling ES6 to ES3. Works pretty good for
me. It does a lot of static code analysis while compiling too.

And it works out of the box with zero configuration

~~~
speg
I decided to use TypeScript for my latest project for similar reasons.

I'm barely using any TypeScriot features. I just wanted a simpler build
system.

------
fallenshell
A few weeks ago I wanted to modernize my JS stack after being out of the web
development scene for a while, as part of learning other programming languages
and the likes. I was dumbfounded at the amount of overengineering, INSANELY
complex build tools, and incredible amount of tools you have to use now to
simply do what JS kids call a "proper" hello world. What exactly are
JavaScript developers trying to demonstrate? That they are capable of
overengineering the simplest thing? (ahem leftpad?) It's getting absolutely
ridiculous. And then if you complain to them about how something is kind of
ridiculous, you are evil, a bad programmer, and should go burn in the pits of
npm. There is also a culture for rewrite the world in JS because JS is the one
and only blessed language. I'm getting inspired for a blog post now...

------
andrewstuart
As an aside, I'm still stuck, having spent the whole day trying to get Babel's
async/await to work. Can someone point me to a web page that includes set of
instructions that actually work for configuring async/await?

This is the reason I wrote the post and I'd really like to get back to
actually programming.

~~~
hzoo
I left a comment on the site - but try
[https://gist.github.com/rauchg/5b032c2c2166e4e36713#file-
pac...](https://gist.github.com/rauchg/5b032c2c2166e4e36713#file-package-json)

npm i -D babel-cli babel-preset-es2015 babel-preset-stage-0 babel-plugin-
transform-runtime

echo "export default async function requireFromTwitter (id) {}" > index.js

echo '{ "presets": ["es2015","stage-0"], "plugins": ["transform-runtime"] }' >
.babelrc

./node_modules/.bin/babel-node index.js

~~~
andrewstuart
That page has a comment that says "Mandatory disclaimer: this is not serious
and not safe."

~~~
hzoo
Haha sorry the code itself is a joke right - I just mean the setup in the
package.json (I posted it above)

FYI: in reference to
[https://twitter.com/rauchg/status/712799807073419264](https://twitter.com/rauchg/status/712799807073419264)

------
joesmo
Totally agree. When I'm spending more time debugging the build tools
configuration than the JavaScript itself, there's something seriously wrong.
Unfortunately, that wrong starts at npm itself and just gets worse from there.

~~~
icedchai
No, the wrong starts with Javascript. ;)

~~~
joesmo
Yes, so true. What a terrible language.

------
erlich
There is a trade off being made. The whole point of the presets system is to
not bring in the modules you don't need. As the Node.js runtime and browser
ES6/7 feature support grows, you will not need certain plugins.

Your title is a little inflammatory: "a lesson in how NOT to design
software.".

Re: Javascript tooling. Yes is it painful. But Babel is designed exactly as it
should be, and the solution to fix your problem is a library that wraps around
it.

~~~
__david__
He did suggest how to fix it—enable everything by default. If you'd like to
argue against that then that's fine, but your response makes it look like you
didn't even read the article.

------
ENTP
I had the same experience. It was really hard to get a react/redux project
started without a swathe of modules and build systems. It became a mission
just trying to set it all up and Babel was a part of that. There appears to be
no way around it to get that stack up and running. I discovered riot.js and
moved to that as there was zero barrier to entry.

------
nstart
Possibly related blog post and discussion

Post: [http://robotlolita.me/2016/01/09/no-i-dont-want-to-
configure...](http://robotlolita.me/2016/01/09/no-i-dont-want-to-configure-
your-app.html)

Discussion:
[https://news.ycombinator.com/item?id=10878623](https://news.ycombinator.com/item?id=10878623)

------
jincheker
It's the nature of JavaScript. And there will be a brand new wheel 3 month
later

