jaredpalmer / tsdx

Zero-config CLI for TypeScript package development
https://tsdx.io
MIT License
11.28k stars 507 forks source link

Explore ESBuild #716

Closed jaredpalmer closed 4 years ago

jaredpalmer commented 4 years ago

https://github.com/evanw/esbuild

agilgur5 commented 4 years ago

So I've already explored this and it's basically a no-go for much of the same reasons swc is (c.f. #495). esbuild also labels itself as a proof-of-concept and not production-ready.

Neither swc nor esbuild follow existing APIs, e.g. .babelrc, tscofig.json, Rollup API, so this requires some mapping of certain options and lots of others just aren't configurable. esbuild also goes further as it's not just a transpiler but a minifer too, which makes it even harder to integrate as it's not single purpose.

If there's a Rollup plugin for either and easy mapping of existing APIs to them, then it's possible to use them in a select number of cases, but I'm not sure there is. The compatibility aspect is missing and redoing that ourselves would be a ton of work. Not to mention, we'd still need Rollup for different formats, tsc for type-checking, Babel for Jest + ESLint, etc etc as neither replaces any of those fully due to the incompatible APIs. We could potentially do a two-pass compilation for plugins, but that approach isn't possible as swc/esbuild wouldn't understand the syntax on first pass. If Babel ran on first pass, then there's no efficiency gain. Ordering problems also exist in current Babel ecosystem (see also #543 ), which might cause even further incompatibilities.

Some other incompatibilities are that esbuild doesn't support watch mode and it doesn't do tree-shaking.

If the compatibility between swc or esbuild improves in the future (or someone adds tooling for compatibility), then I think we can reconsider at that point, but right now the integration is very non-trivial.

agilgur5 commented 4 years ago

Another point on maturity is that both need time to get robust testing, as correctness issues are plentiful. It doesn't matter how fast a compiler is if it's not correct/robust.

We have existing correctness issues in TSDX due to babel-plugin-async-to-promises and those are extremely hard to notice already, so adding something like swc or esbuild would also have to be behind an "experimental" flag for quite some time due to unreliable correctness.

Another toolset in the same space is Rome of course. There's some efficiency gains to be realized by sharing the AST between various tools/phases as well.

schickling commented 4 years ago

Seems like as esbuild is getting a lot more mature, more and more tools (e.g. vite and Snowpack) are being built on top of it.

@agilgur5 would you be up for re-opening this issue?

agilgur5 commented 4 years ago

@schickling if you or anyone else wants this, I would suggest doing the research and listing out how the various problems I've listed have been solved. Just asking for it to be reopened is asking for me to do that (free) work for a feature you want. The best issues and PRs lay out everything and make my (volunteer) job easy and fast.

I did a quick search and here's a few things:

RIP21 commented 3 years ago

@agilgur5 hey mate! Regarding your points current situation is:

ESBuild still has a giant prod disclaimer

Fixed :D

It still doesn't do type-checking and doesn't support certain TS features (it can replace @babel/plugin-typescript, not tsc).

Never intended to and, I guess, they will never try to do that.

It looks like it handles some tree-shaking now, but historically Rollup has had far better side-effect detection than others.

Here in the issue were some comparisons and esbuild was already good. Don't know how it's in the latest versions tho.

Doesn't handle multiple outputs

It seems it's still doesn't, but as it's super quick it's not a problem I guess.

Watch mode is not there It's pretty much done by introducing of incremental API here there are multiple suggestions and ready to be used scripts in the discussion that are using incremental builds for watch mode.

Unsure of plugin support, or if it has Rollup, Babel, or Jest plugins

Regarding Jest, for now, it's a no go mostly as it's super strict with ES spec regarding modules, so there is no way to do jest.mock and similar stuff. More context here

Babel: Also, no AST transformation plugins will be there, as it will be a bottleneck if that would be written in JS I guess.

Rollup plugin is there as well as the Webpack

You can still write some plugins tho, but it's pretty limiting. https://esbuild.github.io/plugins/#plugin-api-limitations

Conclusion: I have no idea TBH :D Performance is a key for sure but stuff should be measured on big libs. I guess the whole pipeline should look like tsc in parallel to minor transforms of babel (optimisation plugins only) and then esbuild to minify/tree-shake/add pure-annotations. The best would be is to get rid of babel tho at all cost, as its parsing will eat up 99% of speed boost I guess. Jest should continue using the old setup until maybe swc gets stable.

The perfect solution will come only with an introduction of Go API for AST plugins for esbuild but it isn't there yet :)

Hope that helps! :)

RIP21 commented 3 years ago

Regarding esbuild-jest, recently there was update that claims that it fixed all the issues with mocking that was present with only one limitation, it will produce CJS under the hood and not ES6, which, I guess, is fine, as there still very much experimental ESM support. Although never tested that myself.