Use ESM for our executables (tsc, tsserver, typingsInstaller)
jakebailey opened this issue · 11 comments
Our libraries are all UMD-ish, because they can be used in Node or in the browser. I didn't change this for the module transform.
However, most of our executables are CJS, as they are only intended to be run within Node. This includes tsc, typingsInstaller, and watchGuard. An exception is tsserver, which contains web code for vscode.dev.
tsc and typingsInstaller both share a lot of code; if they only run on Node anyway, we could potentially raise our minimum Node version to node 12, and ship them as ESM via esbuild's split ESM bundling. If we get vscode.dev off of tsserver (and onto tsserverlibrary), then all three can share code.
In my testing, this reduces our package size by an additional 7 MB, which is a great win.
if they only run on Node anyway, we could potentially raise our minimum Node version to node 12, and ship them as ESM
Isn't Node 14 the earliest version that supports ESM without a command-line flag?
Isn't Node 14 the earliest version that supports ESM without a command-line flag?
Nope, it's enabled by default in Node 12.17+.
But, I would want to target Node 12.20+ as that's when the experimental warning was removed. Technically, Node 12.22 is when it's "stable", but AFAICT 12.20 works fine.
Another totally radical idea would be to just ship ESM now with separate endpoints. It wouldn't behave how people want, as in no tree shaking, but it wouldn't be that much code. tsserver already pulls pretty much everything in anyway, so this wouldn't be all that much extra.
We'd just still have the dual package hazard, and have to get the weirdness of export mappings and self references.
just my 5 cent as i am working on that since ages shipping ESM only is totally fine as that can get easy converted to CJS but thats never the case for CJS also browser support for ESM is more complet then the one for anything else :) also this would finaly open that we can drop our endless forks for other engines then NodeJS. it takes 100 of man years only to workaround your build processes. same for vscode.
maybe you want to play around with:
- http://evmar.github.io/webtreemap/ <= typescript bloat demo
- https://github.com/evmar/webtreemap they use ur project as example
With #51699 merged, tsserver
can now safely be ESM as the web code has been entirely switched to tsserverlibrary
.
That being said, I still haven't quite been able to get the codebase to run in esbuild's code splitting mode, probably due to ordering problems thanks to our codebase's continued circularity.
@jakebailey i have a working ESM build in split mode i can do a PR but i am using Rollup and it is blazing fast and would exactly align with the Dweb and web 4.0 agenda. I am in fact doing that since years so i am familiar with the codebase and type translation. And i am Mainly Tooling author. I am confident that we could get that in a 1 week iteration sorted out.
Can i start the PR?
I have 2 versions of the PR:
- A Version that is simply as is but a split build 1:1 the same files as in Dev Src
1.1. To speed up the loading of split builds we have a tech that we call import hints i go more deep into that if you choose that build but do not fear the fact that it has many modules - A Version that is optimized for the whole ecosystem everything got thoughtful refactored to depend compose able on each other in a way that no big projet that today patches Typescript. Does need to patch it anymore as they can simply extend after import.
my personal favorite is version 2 that's why i did that after i did version 1
version 2 would be equal to my so called dev bundle i create bundles of packages in a way that they are more distributed build ready like putting hashes next to the filename and so.
version 2 with hashes allows for example distributed rolling release including update handling of independent module updates.
It ports the whole package management cycle into the client as service Worker spec does.
if you choose that i can land a PR here i can delay the porting to the monaco editor
as i have plans to let typescript not exist anymore on the long run
Typescript gets a IDL that is only used to add and check type annotations like flow from facebook but i use it as fundamental part to express nativ modules in the ecmascript world.
So this will implement Type Only Modules on the long run and also finish the integration of TC39 proposal type annoations as i land that in chromium directly.
Conclusion
on the long run typescript will get a core part of the IDE as also get ported into Chromium directly via type annotations to allow us to better support hints when working in devtools and other places where we throw errors for components .
I think the scope @jakebailey has outlined here is as far as we're willing to scope this out, and I think this may be a task that the core team is best equipped to tackle.
@DanielRosenwasser your correct i guess you get the rest sorted out with typescript alone in future i am happy that you finally tackle the tech dept it was many years much much work to take this codebase unmodified else there wouldn't exist forks that simply patch files and use the original build process because it was not maintainable.
i love your effort
Mostly related, but I've successfully gotten the TS API itself to run as ESM while being required from CJS: nodejs/node#52599 (comment)
--experimental-require-module
being unflagged with some solution to nodejs/node#52599 would let us just be ESM for everything.