

Benefits for users of TypeScriptįirstly, the performance of the compiler has increased by anywhere from 10 to 25%. properly renaming types with the same name but declared in separate files or avoiding aliasing globals, which are cases that we can avoid or ignore, respectively. This bundler is "dumb" and cannot handle cases that a more widely-usable bundler (like api-extractor) should, e.g. To handle this, I wrote a small-ish (400 line) d.ts bundler that can serve our needs. Since our outputs are bundled, we needed a way to "bundle" our d.ts files too. The new build is also constructed such that it'd be easy to transition to running a bundler on tsc's ESM emit (rather than directly on src). This is tested in CI so we can reliably switch back to tsc's CJS emit if needed. This mode uses tsc to emit CJS, producing modules matching src 1:1. To mitigate the risk of not using tsc's output, I have created a -bundle=false mode for our build. Those performance benefits (and speedy build times) were too good to pass up, and so, our main JS outputs are now produced by esbuild. Unexpectedly, this also brought major performance wins in our benchmarks (see the next section). Unless we wanted to change that expectation and break the world, we needed to bundle.Īs an experiment while working on this conversion, I tried simply running esbuild on our source files directly with a little more tweaking, I was able to produce a working output for our codebase. Additionally, many consumers currently expect to be able to load TS as a single file, and that same file must be usable in Node and the browser.

However, this turns out to incur a big performance penalty our old TS namespaces were just objects, but CJS imports/exports are more expensive than plain objects. This, with a little hand modification, gets us to a place where we can emit CJS and have everything working. Symbols which previously were available "globally" via namespaces are now imported in big import blocks at the top of each file, in such a way that the final code looks nearly identical to the input (but unindented one level). In short, the typeformer project recreates our old namespaces as "barrel" modules, reexporting each file from the barrel module corresponding to its original namespace. To see the conversion process, take a look at the commits in this PR, each of which come with their own descriptive commit message. The bulk of the work to convert the repo to modules is done via automation, followed by a load of changes by hand to completely restructure our build system. "typescript": wait until the next nightly after this is merged.) How?
