← Recipes

阅读中文版本

Use a Makefile as the Task Runner

Define phony targets for build, test, lint, and deploy, mark them .PHONY, and keep the Makefile as the discoverable entry point for the project.

~25 minmakefiletoolingdx

Task

Standardize project tasks behind a Makefile instead of undocumented scripts.

When to use this

Every developer memorizes a different set of scripts and flags, and onboarding means reading the CI config to learn how to build.

Prerequisites

  • GNU Make or a compatible tool
  • A Unix-like shell (or make on Windows)

Steps

1. Define targets for the common tasks with clear names.

Expected output: Tasks are discoverable and consistent.

2. Mark all targets .PHONY to avoid clashing with files.

Expected output: Targets always run when requested.

3. Add a self-documenting help target.

Expected output: Running make lists available tasks.

4. Call the real tools from targets so CI uses the same entry point.

make help

Expected output: Local and CI behavior match.

Troubleshooting

Problem

Target silently skipped

Solution

A file with the target name makes make think it is up to date; mark it .PHONY.

Problem

Windows incompatibility

Solution

Avoid bash-only tricks or provide an alternative for Windows developers; document the requirement.

Limitations

  • Makefiles use tabs, not spaces, which is a common source of confusing errors.
  • Make is not good at dependency-aware incremental builds; use dedicated build tools for that.

Context

Standardize project tasks behind a Makefile instead of undocumented scripts. Every developer memorizes a different set of scripts and flags, and onboarding means reading the CI config to learn how to build.

Steps

  1. Define targets for the common tasks with clear names. Expected: Tasks are discoverable and consistent.
  2. Mark all targets .PHONY to avoid clashing with files. Expected: Targets always run when requested.
  3. Add a self-documenting help target. Expected: Running make lists available tasks.
  4. Call the real tools from targets so CI uses the same entry point. Expected: Local and CI behavior match.
.PHONY: help build test lint
help:
	@grep -E '^[a-zA-Z_-]+:' Makefile | cut -d: -f1
build:
	pnpm build
test:
	pnpm test
lint:
	pnpm lint

Verify

  • Tasks are discoverable and consistent.
  • Targets always run when requested.
  • Running make lists available tasks.
  • Local and CI behavior match.

Limits

  • Makefiles use tabs, not spaces, which is a common source of confusing errors.
  • Make is not good at dependency-aware incremental builds; use dedicated build tools for that.