
Deploying ES2015+ Code in Production Today - robin_reala
https://philipwalton.com/articles/deploying-es2015-code-in-production-today/
======
WorldMaker
One additional thing to further the article's points is to mention @std/esm
[1][2], doing a similar thing for node module loading. Between the tools the
article mentioned and this library we are quickly approaching that big
inflection point to start distributing only ES2015+ modules for many
libraries.

[1]
[https://www.npmjs.com/package/@std/esm](https://www.npmjs.com/package/@std/esm)
[2] [https://medium.com/web-on-the-edge/es-modules-in-node-
today-...](https://medium.com/web-on-the-edge/es-modules-in-node-
today-32cff914e4b)

~~~
styfle
I read about @std/esm and I wasn't totally sold on it. But now that I read the
browser side of the story, I think it makes way more sense to make use of
@std/esm in all packages on npm.

The old way of doing things was write for node, and transpile/polyfill the
browser with browserify/webpack/etc. But the amount of bytes you ship to the
browser really matters. So now the new way of doing things is to write for the
browser and transpile/polyfill node which is what @std/esm is doing.

This is explained a little better in the r2 readme:

[https://github.com/mikeal/r2](https://github.com/mikeal/r2)

~~~
WorldMaker
I agree, a large amount of npm code is always going to be targeting browsers
for many uses and the better the Node world converges with browser APIs, the
easier it is for everyone.

It makes sense from the Node side of things too, because there's an ability to
sometimes borrow the browser-hardened native implementations of "web" APIs
directly from partner tools like Chromium, v8, and even ChakraCore. A rising
JS tide can lift all boats, and the more "universal" the web platform is the
easier it is to develop for.

Also, File I/O is still a bottleneck in Node, even if nowhere near the
bottleneck of browsers requesting files over HTTP, and it feels like
webpack/rollup is starting to be more of a thing on server-side/NodeJS side,
because there are benefits to reducing the bytes you need to read from disk in
startup times of NodeJS apps, too. So it's interesting seeing some
optimization tools converge on that side of the fence as well.

------
deathanatos
> _async /await, classes, arrow functions, etc. However, despite the fact that
> all modern browsers can run ES2015+ code and natively support the features I
> just mentioned_

What is everyone's cutoff for de-supporting a browser? According to
caniuse.com[1], >30% of browsers _don 't_ support the mentioned feature-set;
that seems like … a lot.

(<script type="module"> is listed at 60% unsupported, which seems very high,
but his point that if you allow it, you should allow everything else mentioned
seems sound. I also heavily agree w/ his point about delivering modern JS, and
letting end consumers transpile as needed.)

[1]: [https://caniuse.com/#feat=async-
functions](https://caniuse.com/#feat=async-functions)

~~~
rayshan
If not supporting IE, a good gauge is evergreen browsers (Chrome, Firefox,
Edge) and Safari going back 2 major versions. This means supporting 2 years of
Safari 9.x and 10.x as of today. macOS doesn't upgrade as often as evergreen
browsers.

~~~
timdorr
Safari 11 just came out this week, so you can drop 9.x soon.

~~~
robocat
Note many older Apple devices are stuck on iOS9 or iOS10 - a good list is
here:

[http://www.everyi.com/by-capability/maximum-supported-ios-
ve...](http://www.everyi.com/by-capability/maximum-supported-ios-version-for-
ipod-iphone-ipad.html)

So it depends a little upon your user demographic (or whether you want to keep
supporting users or companies that can’t afford to upgrade their device).

~~~
timdorr
Also keep in mind that in addition to limited language feature support, many
of those older devices have limited performance capabilities as well.

So, while you may be able to get your code to run on them, it might not be a
great experience and of limited value to your customers to even try offering
support.

------
skrebbel
I love this, but I'm missing a key piece to make this effective for non-tiny
code bases.

The author proposes using 2 webpack configs, one for es2015 and one for es5.
That means running webpack twice from scratch. This, in turn, means you can't
effectively use webpack's devserver because that's just a single instance with
a single webpack config.

The author's boilerplate [0] "solves" that by hand-coding a watcher based on
chokidar which just rebuilds both files on every change. On our code base,
clean webpack builds take minutes (and when babel is even configured to
exclude /node_modules/, as the author recommends against). If we'd follow the
author's advice, we'd be waiting for minutes every time we make a change.

Anyone got a good idea here? The best I can come up with is to use the es2015
build (but with node_modules excluded) in dev mode, and then for staging and
production, running webpack twice as the author suggests. That makes the dev
version rather different from both the production es2015 output and the
production es5 output, however, so if there's any bug in the chain anywhere
(babel bug, webpack bug, babel-env browser support table error, etc etc) we
may not always find it.

In all honesty that itches me a bit (even though by skipping uglify in dev
mode we already depend on at least 1 tool being essentially bug-free). Any
ideas?

[0] [https://github.com/philipwalton/webpack-esnext-
boilerplate](https://github.com/philipwalton/webpack-esnext-boilerplate)

~~~
crooked-v
Actually, I believe you can already run webpack-dev-server with a multi-config
just by making your webpack.config.js export an array instead of a single
object. The article seems unaware of this capability, but you should be able
to have both builds be part of a single webpack config file.

See [https://github.com/webpack/webpack-dev-
server/blob/master/ex...](https://github.com/webpack/webpack-dev-
server/blob/master/examples/webpack-config-array/webpack.config.js) for a
simple example. I've used this before for web worker scripts (which require a
different environment than the DOM) alongside a normal build.

~~~
philipwalton
I didn't know about that. I'll look into it!

------
redonkulus
This solution for loading the scripts is great. We have been experimenting
with this and browser sniffing was our approach. Will start testing this new
approach. Really makes integration and fallback much easier to manage.

------
mijamo
One thing missinh here is that dependencies are still published as ES5,
sometimes with ESM as an addition. There is no easy way to provide a library
with async/await as of today. We would need module:es2017 property in
package.json for that. It mitigates a lot the benefit becausr in most code
bases dependencies represent the majority of the final JS, and they gain
nothing with this approach.

------
reificator
Was mildly interested at the headline, but the fact that this works even for
static hosting is pretty great. To be honest I was expecting browser sniffing.

------
Vinnl
Relevant to module publishing: Axel Rauschmayer's proposal for package authors
to start packaging untranspiled code _in addition to_ legacy Javascript:
[http://2ality.com/2017/06/pkg-esnext.html](http://2ality.com/2017/06/pkg-
esnext.html)

------
mkishi
If you have an app shell being served from a Service Worker, you can also
assume the browser supports most modern features!

------
agnivade
Excellent ! I was thinking a lot about this lately. Someone beat me to it ..
dang it.

------
shaydoc
Fab article.

------
spraak
Edit: Sorry, I didn't read to the "Is this really worth the extra effort?"
section.

~~~
mkishi
Do you disagree with the reasons given in the "Is this really worth the extra
effort?" section or did you just miss it?

