4 ms·
The problem that I find with Makefiles, in Node projects, is that node scripts and tools are pretty slow to startup and pretty much all of them have some run-on
by augusto-moura 2y ago
The problem that I find with Makefiles, in Node projects, is that node scripts and tools are pretty slow to startup and pretty much all of them have some run-on-all-files type of setup
So, for example, instead of running the typescript compiler for a single file
tsc src/index.ts
You are better suited to run the compiler to the whole repository:
tsc --build ./tsconfig.json
Which implements incremental building and dependency tracking automatically.
For this case having make run tsc for each file individually hurts performance pretty bad. Something like this will not scale very well:
src/%.js: src/%.ts
tsc $<
There's definitely a overlap where each JS tool implements its own incremental building, cache system and dependency resolver. Eslint, prettier, npm, webpack could all benefit from being more Unixy and forwarding the task management to a tool to rule them all.
Things are changing though, and tools like swc and esbuild are getting pretty fast. And there a few attempts for an universal build system on NX and TurboRepo. My dream scenario is where we get a single command interface, similar to gradle or bazel, where you just run `tool build` and everything gets setup for you without fuzz
- pushupentry1219 2y agoI haven't read the article yet but why not make a PHONY target that just runs that build command? .PHONY all all: tsc --build ./tsconfig.json
- augusto-moura 2y agoYou could, but the you lose most of make's benefits, this way you are only using make as a script bundle. Looking back now it does align with what the article is proposing. But I still a bit annoyed that we don't get proper use of Makefiles, and that we need to reinvent incremental building for every tool
- nsonha 2y agoUsing make but don't have any artifact and dependency is just choosing the wrong tool for the job. It's the whole point of the tool.
- Leynos 2y agoIn my previous job, I used Make for my asset pipeline and compilation of javascript. At some point, I discovered esbuild and realised that I had to split the file in two for tasks that had to be done sequentially and those that could be done in parallel. Esbuild still had dependencies, but needed to be run only once for those dependencies. Still got great results ultimately. Going from something like a minute to four seconds.
- cerved 2y agosame problem in Java
- tacone 2y agoAn interesting alternative is the javascript+typescript approach that Svelte uses. Typescript is only used for the typechecking, there is no transpilation for running the app since all the run-time code is written in plain javascript.
- avar 2y agoYou can rather easily write rules with GNU make that sit at the comfortable middle ground between these two. E.g. if you have 1000 JS files to generate from 1000 source TS files you'd "shard" them dynamically by having them batched N at a time, e.g. batches of 10 or 100. You need to dynamically evaluate Makefile rules into existence for that to work. I haven't used "tsc", but most compliers with start-up overhead care if you invoke them for every file. But if you can amortize that over N any resulting slowdowns are generally lost in the noise. Why do that? Because if you have other rules that rely on all that JS being built, it can be much faster overall. If some of the files are finished you can use free CPU cores for those follow-up rules, as opposed to waiting for "tsc" to build every last one. It also makes your build system UK much better. I know some think "good UX" and "GNU make" are diametrically opposed concepts, but being able to ask it "what do I need to incrementally generate to make X" for any file is really useful. That works much better if your build system doesn't have one big "do all the things" step that's essentially reimplementing most of GNU make.