Incremental Compilation with Symlinks

So it turns out that TypeScript doesn’t really have incremental compilation. This means if I rely on some 3rd party modules then recompiling anything that depends on that 3rd party module will transitively recompile everything. I understand that TypeScript is not a build system so delegating those responsibilities to one is a sensible design decision. The trouble with build systems is they can get pretty hairy pretty fast and ideally I want to avoid the overhead of one. Fortunately we can avoid the hairy parts of a build system by using a few symlinks and declaration files.

The declaration files will let us avoid recompiling 3rd party modules. The way we’ll do that is by symlinking a relative folder reference to one that only contains declarations produced by the initial compilation.

Our starting point is the following folder structure

The 3rd party module I’m using is RxJS and main.ts is the only thing that needs to be recompiled in this example after the initial compilation. For demonstration purposes this is the main file

Putting 3rd party imports in a single file just simplifies some of the management and is not strictly necessary

All it does is import and re-export the relevant parts of RxJS. You don’t have to do this but I think it’s useful for tree-shaking when bundling. If you import everything then tree-shaking won’t be as useful and the final bundle size will be larger.

Now the trick is that for full compilation we point rxjs to sources/rxjs and copy over all the declaration to declarations/rxjs. After copying the declarations we can change the symlink to declarations/rxjs and avoid recompiling RxJS all over again. All of these tasks live in a rake file

The compilation from a clean start is ~12 seconds

Partial compilation is a lot better. The declaration files still have to be loaded and parsed but we avoid the actual compilation of RxJS

I’m pretty happy with this solution. It avoids implementing a full build systems and is still fast enough for having an interactive feedback loop.