DEV Community

Cover image for Bringing Modern JavaScript to Libraries

Bringing Modern JavaScript to Libraries

Gary Chew on July 31, 2020

tl;dr: To bring modern JavaScript to our libraries, we should adopt a new "browser2017" conditional export key. The "browser2017" key points to mo...
Collapse
 
voluntadpear profile image
Guillermo Peralta Scura

Even though there are drawbacks, shifting transpiling responsibility to application developers seems the most escalable approach. I think these drawbacks of potential silent breakages and transpiling errors can be vastly mitigated once the tooling and community adopts this extensively.

Collapse
 
jamescoyle profile image
James Coyle

I think the esnext option makes the most sense. There is no way for a library to know what its users are targeting so it can only make best guesses and support a couple of different options. It makes more sense to leave the transpilation to the consumer who can have more control over the level of support they need.

This makes things easier for the library developers as they can just focus on targeting the current browsers and, with the right tooling, the consumers of the library can easily transpile that code to support whatever configuration they need. No more messing around getting commonjs modules and esmodules to work together and much less useless code that adds unneeded browser support when you are creating a bundle for modern browsers. We can all just write code once for modern browsers with the latest widely supported features and then let the build tools handle legacy support.

I feel like the issue of outdated transpilation could be alleviated by having the build tools check for updates automatically and trigger warnings. Alternatively, assuming all transpilation will be done through babel, the library could add babel as a peer dependency with a minimum working version that would then trigger missing dependency warnings if the consumer uses an older version which doesn't support the newer features.

Collapse
 
sirseanofloxley profile image
Sean Allin Newell

Excellent articl with an obvious amount of effort, research, and experience. 👍

Collapse
 
y_nk profile image
Julien Barbay • Edited

Honestly TLDR but by glancing I cannot stress enough how bad is a world where you need to build an application for "js2020", "js2019", "js2018", "js2017" and so on. Soon enough we'll have the division of python 2/3 in the javascript world in libraries.

"We’ve left transpilation to package authors, but have established no mechanism for them to publish a modern version of their code."

Here you have the solution of your problem : just don't transpile libraries. Serve them fresh with the latest tc39 stable features and don't assume how people want to consume them. If they want to transpile down to es5, let them do. If some library author publishes a library with older javascript features, it'll work as much thanks to backward compatibility.

Don't assume on how people will use your code. Serve it clean no matter what. Problem solved.

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt • Edited

tl, but if I expect loyalty from users, wouldn't it be better to use something near esnext, and notify users to use latest browsers, if some features are not supported?

Especially the case with web apps.

However, for static websites (probably with API's), I believe it should be able to run even with JavaScript disabled. (Still, CSS supports can still be an issue, not sure about HTML5.)

Also, can anyone please conclude, what the preferred settings for Babel / tsc / browserify / Snowpack? (I have used Rollup, but I feel it can be unreliable.)

Alternative Solution: Multiple Entry Points by Year

Another thought -- (pre-)building on the CDN based on User Agents?

Collapse
 
_developit profile image
Jason Miller 🦊⚛

User Agents are an increasingly unreliable mechanism for determining the compile target. Also, esnext does not mean the latest browsers, it means the latest spec version. The current versions of Safari and Firefox are missing support for some ES2019 features, let alone Firefox ESR or Safari for iOS. An esnext target is not connected to any real-world usage, it's purely a theoretical syntax level based on in-flight specification work. Ultimately, the browser implementors decide which JavaScript features ship and which don't.

Collapse
 
pavelloz profile image
Paweł Kowalski • Edited

Very good idea and important topic to promote. In general I can't wait till babel will be thing of the past for normal developers.

Collapse
 
alexmacarthur profile image
Alex MacArthur

This is super insightful! I love that there's movement behind standardizing solutions like this. Question: you mention that Webpack has implemented conditional exports... any idea where I might be able to try that out? I'm assuming it'll be in v5?

Collapse
 
garylchew profile image
Gary Chew

Yup, v5!

Collapse
 
pengeszikra profile image
Peter Vivo

I miss the pipeline operator again

Collapse
 
sebastienlorber profile image
Sebastien Lorber

One solution is to adopt ReactNativeWeb :p
RN libs are published untranspiled, so it's already the responsibility to the app to transpile those libs