Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Deploying ES2015+ Code in Production Today (philipwalton.com)
177 points by robin_reala on Sept 21, 2017 | hide | past | favorite | 25 comments


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 [2] https://medium.com/web-on-the-edge/es-modules-in-node-today-...


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


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.


> 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


On GOV.UK: take the most used browser from the stats, then add on the next most used and repeat until you get to 95% of the total. At that point start looking at ease of support. Typically browsers will be dropped from the testing list at ~0.4%, unless there’s a security need to remove support.


Forgot to link to the page on GOV.UK with that method and the current set of recommended browsers: https://www.gov.uk/service-manual/technology/designing-for-d...


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.


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


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...

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).


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.


We consulted two eCommerce companies into dropping Safari support as such.

During AB tests, sales actually went up


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


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... 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.


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


You're right about it not working for webpack dev server, and I agree that it's unfortunate, but I think webpack will evolve to accommodate this.

[EDIT: it looks like this is already supported, here's the documentation explaining how to do it: https://webpack.js.org/configuration/configuration-types/#ex...]

Service Worker already introduced the need (or you could argue possibility) to have multiple configs since SW code has a much different transpiling baseline compared to legacy browser code. And module code just adds one more level to this.

I think webpack dev server will update if this practice becomes popular, but for the moment I think your idea of only building the es2015 build in dev mode is probably the best temporary solution (as long as you make sure to run your test suite in multiple environments and include the legacy build there).


Test your production builds, that's the solution. Both with unit tests (in CI) and sanity testing.


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.


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.


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.


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


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


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


Fab article.


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


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




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: