Closed cowboyd closed 4 years ago
Hi Charles - just a foreword, this reply got a little long. My apologies in advance! In terms of a straightforward answer to your petition, you can actually already use a browserslist
key in package.json or a .browserslistrc
file to specify your browser/node support target. It governs the syntax output in all files except .modern.js
(which in your description you would actually want to disable).
Now, on to the underlying question: how can we publish modern code to npm without breaking everything?
FWIW, unless you're specifically targeting only Node.js, publishing a package as modern-only is going to create a lot of confusion. Create React App transpiles node_modules by default, but no other popular bundler configurations do - that means most projects simply aren't set up to handle modern code in npm packages.
That's not to say I don't want to fix the whole "modern npm packages" issue - very much the opposite. I believe there is a way forward, but from both my own experience and in talking to the folks who maintain downstream tooling, publishing modern-only browser packages isn't going to get us there. Instead, I think we may be in a position to standardize on the existence of an Export Map as the indicator that a package provides modern code. Because Export Maps have a designated mechanism for falling back to the package.json main
field, they can also be used to fall back to ES5.
However, there's a huge missing piece. In all of these approaches, from modern-only packages to backwards-compatible multi-mode packages, the syntax we refer to as "modern" is an arbitrary point-in-time decision that happens on a per-package basis. Scale that up to the whole ecosystem and we end up having no way to know if a package is ES3 or ES2020 - bad for performance, and potentially impossible to work with. The "modern" name used by Microbundle refers to "the JavaScript syntax supported in all browsers that implement Githubissues.
We recently decided that we wanted to drop support for older browsers and move to not transpiling generators and async/await. Our problem is that (using the recently released 0.12) we can't seem to generate a modern JavaScript that is transpiled to both commonjs and esm, and it's unclear whether it is possible to do this with
microbundle
today.Given the churn around #518 #582 #570 and what is hopefully the final fix with #605 it has me wondering if things would be simpler both internally and externally if "modernity" were treated as type of content rather than a module format.
In other words, the module format could vary independently of the transpilation target. That way you could run something like:
And microbundle would emit a matrix of modules crossed by content type and module format such as:
This would give package maintainers the ability to target modernity (or lack thereof) and be able to deliver easily regardless of the consumer's preferred module format.