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 targetBigger 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
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