When Babel 6 came out, it was hard for a lot of packages to upgrade because it was essentially an entirely different category of thing than Babel 5. So what happened was that some packages upgraded, and some didn't — at least not straight away.
Some projects took the prima facie enlightened view that packages should expose untranspiled code, so that the consumers of that code could determine for themselves what needed to get transpiled based on the environments they supported.
That was a costly decision. If I was the author of an app that was using Babel 6, I couldn't import a library that was still using Babel 5 and shipping untranspiled code (because the configs were completely incompatible), and vice versa. Frankly, it was a bloody nuisance. We are bad at anticipating these sorts of issues. It will happen again at some point.
Adding a few extra bytes to pkg.main
or pkg.module
is a small price to pay for things just working. As well as avoiding the aforementioned headaches, it means that your builds are a lot quicker. I don't want to run my node_modules through Babel.
Right. So you're a library author, and you want to use async
/await
and all that stuff. You have a few options here:
- Don't. It transpiles badly. Honestly, we managed for long enough without it — it's not that hard.
- Say that you don't support environments without
async
/await
. That's totally fine. I don't support environments withoutArray.prototype.filter
. - Include your
src
code in the npm package. If someone really wants to use your futuristic code in an environment you don't support, let them. Just make sure you also include pre-transpiled bundles.
A lot of developers believe that the priority is to ship the leanest, most optimised code possible. I disagree. The priority is to ensure that people can consume code with the least amount of faffery. A novice developer should not have to learn about transpilers in order to use your library.
Shipping code that works out of the box is just basic politeness. I've said this in the past, and I stand by it:
It’s the difference between giving someone raw ingredients and a cooked meal — if you went to a restaurant and ordered a burger, you’d be pretty mad if they gave you half a pound of minced beef and a frying pan instead.
Shipping the leanest, most optimised code is something experts care about. Experts have the knowledge and incentives to invest time in the kinds of workflows that involve transpiling other people's code. That should not be the default.
Thanks for writing this!
It's funny: I feel like I agree with 98+% of this, but my headline for it would be: "Libs should start shipping untranspiled code". Why? Because I think your option #3 is a good way forward for the community, and I care about the possible optimizations we can get from untranspiled code in the majority of browsers that support the new ES features.
(To be honest, it never even occurred to me that "shipping untranspiled code" meant not also shipping transpiled code and putting that entry point in for
pkg.main
. This is why communication over Twitter is terrible!)I do, however, think that making option #3 truly workable probably requires some new
package.json
entry that would indicate what level of ES the code is written in. That would allow bundlers/tooling to effectively choose when to include untranspiled code, when to partially transpile the untranspiled code, and when to fall back to fully pre-transpiled code. Does that make sense?Thanks for breaking out of 140 chars and for your nearly unending service to the JS world!