mohkale / jekyll-tsc

compile typescript files on your jekyll blog
MIT License
9 stars 2 forks source link

Very Slow Compiles #4

Closed agatha2 closed 1 year ago

agatha2 commented 1 year ago

I am finding that compilation is very slow (14s now). I am not sure, but I think the plugin recompiles all typescript files in the entire site when any one of them changes, which would definitely explain it.

The caching mechanism needs to be upgraded to support file granularity.

mohkale commented 1 year ago

@agatha2

You're correct this plugin recompiles everything on each change. This is because the plugin does not know the dependencies between files and can't reliably skip recompiling files when their dependents have not changed. For example file X imports file Y, Y changes and you have to recompile X because they've both changed. This is just one of the many reasons.

I'd welcome any attempt to improve this situation, although to be frank I no longer use jekyll and am unlikely to do anything with this project. If you'd like an alternative you may want to setup webpack to smartly transcompile typescript to javascript and just have jekyll pull in the output.

agatha2 commented 1 year ago

I no longer use jekyll and am unlikely to do anything with this project

That's unfortunate; this project seems to be the main TypeScript plugin for Jekyll (I know of only one other, and it seems like it never actually was made to work). I've been working on my own plugin, but I'm struggling since I find Ruby cursed . . .

For example file X imports file Y, Y changes and you have to recompile X because they've both changed.

I don't see that this is necessary? You recompile Y and then the already-compiled X loads the new version. What I've been finding is that the TypeScript compiler does a lot of this lifting for you anyway. A key example is that if you change a file, when you recompile, it will automatically compile all imported modules—with caching, AFAICT, so the above actually gets handled correctly regardless.

It seems that the documentation for the compiler (and e.g. for tsconfig) seems to really want to operate on a whole 'project', instead of individual files, presumably with file-up-to-date caching provided by the compiler. This goes against Jekyll's philosophy of wanting to manage everything itself, wherefore the conflict.

After some thought, I think something that might work is to oblige both Jekyll and the TypeScript compiler. You copy all the TypeScript into a temporary directory and then let the compiler compile it as a project instead of file-by-file. Then you copy all output to the build directory. The main complexity is keeping the output files and the input files all consistent with the project itself; all the dependency checking and suchlike is handled by the compiler.

Even simpler is to just build from the source into the temporary directory (you can't build directly into the output since Jekyll will eat it on regen), and then copy the temporary into the output after the build. Then the compiler manages almost everything (at most maybe you'd just have to clean up old JS files from deleted TS files).

I don't know if those approaches actually work in practice, though; the compiler seems simultaneously really powerful and really stupid (e.g. unless you specify --rootDir it just mungs paths willy-nilly and inconsistently, or how it can't compile individual files as modules or with a tsconfig for no legitimate reason).

agatha2 commented 1 year ago

FWIW, I got my plugin working: https://gist.github.com/agatha2/fb11e8db8b6419889cfb297e46c71212

It uses the approach I sketched above. It runs on the same codebase in about 2 seconds for an incremental build, and seems to cover at least the use-case I need. Perhaps it will be useful to someone who finds this issue.

mohkale commented 1 year ago

Cool. I'll forward anyone who asks about this in future to your plugin.