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<p>So, for example, instead of running the typescript compiler for a single file<p><pre><code> tsc src/index.ts
</code></pre>
You are better suited to run the compiler to the whole repository:<p><pre><code> tsc --build ./tsconfig.json
</code></pre>
Which implements incremental building and dependency tracking automatically.<p>For this case having make run tsc for each file individually hurts performance pretty bad. Something like this will not scale very well:<p><pre><code> src/%.js: src/%.ts
tsc $<
</code></pre>
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.<p>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
I love make because it has simple syntax, is language-agnostic, and provides consistent builds regardless of the tooling used. This is especially visible if you combine it with multi-language projects (e.g., C/Java/JS all in one).<p>Instead of running multiple commands, I can type "make prepare ship" and the magic starts. While it has its challenges with language-specific tasks, use language-specific build tools, like true Unix philosophy demands :D. When I need language-agnostic dependency management, make's simplicity is still unmatched compared to modern alternatives. And no, bash scripts can't match this with ease.
I find that <a href="https://github.com/casey/just">https://github.com/casey/just</a> is a great answer to a lot of problems in this thread.
I have a justfile in all my projects now and I'm very happy.
The anti-make-reinvent-everything mentality has bugged me for decades. I never understood why every language seems compelled to reinvent the build system. Especially when the output is file based.
I like this, package.json starts to look really ugly when you build up lots of scripts that need to run interdependently. For example some stubbed back ends, front end, some auth service, etc. You end up with ugly long npm scripts with &&s everywhere. However for this sort of thing, personally I'd rather use docker compose, dependencies are explicit and declarative, like this I guess. You can define
health checks for services with docker compose too.
There is an even simpler way, just use a bash file with each function being a task, saves you from the .PHONEY hack and the "bash but not really bash" quirks of makefile.<p><a href="https://github.com/adriancooney/Taskfile">https://github.com/adriancooney/Taskfile</a>
Why not just use shell scripts instead of trying to work around make’s weirdness to make it do something it wasn’t designed for?<p>If make is available, odds are that a bash-compatible shell is too.
I like make but I don’t understand the logic here. If you’re going to install node anyway, why be so against using node for scripts? Perhaps less of an issue these days but make also isnt included in windows.
If you’re going to use make, use just instead:<p><a href="https://github.com/casey/just">https://github.com/casey/just</a>