Another possibility, albeit much more dramatic, is only using modules, if your audience is 100% modern browsers.
At my previous job we imported our Google Analytics data into caniuse.com [1] and noticed that >99.9% of our app users were in modern browsers. Same for the public facing website. There was one single visit from someone using IE, but the application wouldn't load for him anyway.
Using those stats we were able to also remove a bunch of polyfills. The next step we were planning was either using a CDN for dependencies or something like Pika [2].
Unfortunately both Vue.js and React/Preact [3] require a compilation step for a good experience IMO. Otherwise I'd just skip the compilation step altogether and write JS like in the old times.
Another reason for keeping a compilation step is it's not just about scripts, it also generates the assets (stylesheets, images, 3d models, etc) and does postprocessing like calculating SRI hashes.
I use Vue.js old style without any compilation for a reasonably complex app and it’s pleasant enough.
Node.js backend uses Pug for templating, each template includes a script template file. These template files are built with Make and load either a minified bundle (made with terser) or just a bunch of plain JS depending on the value of NODE_ENV.
If you really want to remove the compilation step you can use htm (also originally by the same author of the blog and Preact):
https://github.com/developit/htm
We actually had full support for older browsers and even tested for them before that.
This was our SaaS-like application, btw, which was closed to the public. Btw, the public website also had a number of modern browsers close to 99%.
Trust me, if we actually needed extra support our sales team would have made us well aware ;)
EDIT: Also, this is sort of a statement. I'd rather let old browsers die. I think it's ok to say "no" to customers sometime. I want the web to evolve, might as well play a part on it, forcing people to upload their browsers, or letting their IT department know their outdated browsers are getting in the way of their productivity.
It's hard for me to see how you can have "full support for older browsers" given that, as per the comment I've linked below, your application wouldn't load for an IE user.
The best solution remains in my opinion browserslist-targeted compiling. I don't think it makes sense to pretend you can/should write non-trivial JS today without a build step, especially if you're worried optimizing delivery. Are you seriously going to fret about delivering unnecessary polyfills to modern browsers while simultaneously delivering unoptimized code and styles because you felt like going old school?
You can write tomorrow's JS and CSS today while explicitly supporting whichever of yesterday's browsers you know you need to, and have the delivered code improve over time as older browsers are phased out without you having to rewrite it.
Excellent writeup! It's a tricky thing to get right, in part bc it keeps changing. Good job reinforcing the need for devs reading this to understand that and to err on the side of making deliberate, rational choices for their circumstances, vs "here's the best way to do it" leading to ignorant cargo-cult / copy-paste nonsense.
The two drawbacks of module/nomodule that I don’t see being discussed often:
- babel compiles async/await down to regenerator when using modules: true (at least for now)
- the definition of “modern” browsers will change eventually and module/nomodule detection will not be relevant
There are a few cases where syntax compilation is split up cleanly, but when you dig into the internals of preset-env, transforms are rarely that isolated. That being said, "watch this space"...
At my previous job we imported our Google Analytics data into caniuse.com [1] and noticed that >99.9% of our app users were in modern browsers. Same for the public facing website. There was one single visit from someone using IE, but the application wouldn't load for him anyway.
Using those stats we were able to also remove a bunch of polyfills. The next step we were planning was either using a CDN for dependencies or something like Pika [2].
Unfortunately both Vue.js and React/Preact [3] require a compilation step for a good experience IMO. Otherwise I'd just skip the compilation step altogether and write JS like in the old times.
[1] https://caniuse.com/feed/116
[2] https://www.pika.dev/about/
[3] https://preactjs.com - a library made by the TFA author :)