Part 7 · 1 chapters · ~8 min

make and Task Runners

make's model (targets, prerequisites, recipes, timestamps), pattern rules and automatic variables, .PHONY targets, self-documenting Makefiles, package-manager scripts, just, Taskfile and mise, keeping CI and local commands identical, and when a real build system (Bazel, Nx, Turborepo) is worth it.

8

A project Makefile

code
# Makefile: recipes must be indented with a tab
.PHONY: help setup test lint dev migrate
help:   ## list targets
	@grep -E '^[a-z-]+:.*##' $(MAKEFILE_LIST) | awk -F':.*## ' '{printf "  %-10s %s\n", $$1, $$2}'
setup:  ## install dependencies and tools
	mise install && npm ci
test:   ## run the test suite
	npm test
lint:   ## lint and typecheck
	npm run lint && npx tsc --noEmit
dev:    ## run locally
	npm run dev
migrate: ## apply database migrations
	npx prisma migrate deploy

# file targets: rebuild only when inputs change
dist/app.js: $(wildcard src/*.ts) package.json
	npx esbuild src/index.ts --bundle --outfile=$@        # $@ = the target

Bigger repositories outgrow make: Nx and Turborepo cache task results across a JavaScript monorepo, and Bazel offers hermetic, remotely cached builds across languages at the cost of significant setup (Platformization course).

MAKE AND TASK RUNNERS
one command per task, documented in the repo
makeTargets, dependencies andtimestamps: rebuild only whatchanged..PHONYTargets that are commands, notfiles (test, lint, deploy).package scriptsnpm run, composer scripts:per-language runners.justA command runner with make-likesyntax and fewer surprises.Taskfile, miseYAML task runners; mise also pinstool versions.the pointmake test works for every engineerand in CI, the same way.
swipe the figure sideways, or tap expand for full screen
1/4
make
make compares file timestamps along a dependency graph and runs only the rules whose inputs changed: the original incremental build tool (1976).
timestamps + dependenciesincremental builds