完整项目模板
三个可直接套用的完整 Makefile,覆盖最主流的项目形态。复制后按需增删即可。
Go 后端服务
.DEFAULT_GOAL := help
# ---- 变量 ----
BIN := app
VERSION := $(shell git describe --tags --always 2>/dev/null || echo "dev")
COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
DATE := $(shell date +%Y-%m-%dT%H:%M:%S%z)
LDFLAGS := -X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.buildDate=$(DATE)
PKGS := $(shell go list ./...)
.PHONY: help build test run lint fmt tidy clean docker-build
## build: 构建二进制到 bin/
build:
@go build -ldflags "$(LDFLAGS)" -o bin/$(BIN) ./...
## test: 运行测试(带竞态检测与覆盖率)
test:
@go test -race -cover ./...
## run: 本地运行
run:
@go run ./cmd/server
## lint: golangci-lint 静态检查
lint:
@golangci-lint run
## fmt: 格式化代码
fmt:
@gofmt -w .
@goimports -w . 2>/dev/null || true
## tidy: 整理依赖
tidy:
@go mod tidy
## clean: 清理产物
clean:
@rm -rf bin/
## docker-build: 构建 Docker 镜像
docker-build:
@docker build -t $(BIN):$(VERSION) .
## help: 显示帮助
help:
@echo "可用目标:"
@awk -F':.*## ' '/^[a-zA-Z0-9_-]+:.*## / {printf " %-14s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
多平台交叉编译
一条命令产出 Windows / Linux / macOS 三平台产物:
.PHONY: build-all
build-all:
@mkdir -p dist
@GOOS=linux GOARCH=amd64 go build -o dist/$(BIN)-linux-amd64 ./...
@GOOS=darwin GOARCH=arm64 go build -o dist/$(BIN)-darwin-arm64 ./...
@GOOS=windows GOARCH=amd64 go build -o dist/$(BIN)-windows-amd64.exe ./...
或封装成变量循环:
PLATFORMS := linux/amd64 darwin/arm64 windows/amd64
.PHONY: release
release:
@mkdir -p dist
@for p in $(PLATFORMS); do \
os=$${p%/*}; arch=$${p#*/}; \
ext=""; [ "$$os" = "windows" ] && ext=".exe"; \
echo "▶ 构建 $$os/$$arch"; \
GOOS=$$os GOARCH=$$arch go build -o dist/$(BIN)-$$os-$$arch$$ext ./... || exit 1; \
done
🚨 recipe 里 shell 变量要用
$$os转义,Make 变量才是$(os)。两者混写是交叉编译脚本最常见的错误。
Docker 构建 + 推送
IMAGE := yourname/app
TAG := $(shell git describe --tags --always 2>/dev/null || echo "latest")
REGISTRY := docker.io
.PHONY: docker-build docker-push docker-all
## docker-build: 构建镜像
docker-build:
@docker build -t $(IMAGE):$(TAG) .
## docker-push: 推送镜像
docker-push:
@docker push $(REGISTRY)/$(IMAGE):$(TAG)
## docker-all: 构建并推送
docker-all: docker-build docker-pushNode / 前端项目
.DEFAULT_GOAL := help
.PHONY: help install dev build test lint clean
## install: 安装依赖
install:
@npm install
## dev: 启动开发服务器
dev:
@npm run dev
## build: 构建生产版本
build:
@npm run build
## test: 运行测试
test:
@npm run test
## lint: 代码检查
lint:
@npm run lint
## clean: 清理构建产物
clean:
@rm -rf dist/ node_modules/.cache
## help: 显示帮助
help:
@echo "可用目标:"
@awk -F':.*## ' '/^[a-zA-Z0-9_-]+:.*## / {printf " %-12s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
全栈混合项目(Go 后端 + 前端)
一个 Makefile 同时管理前后端:
.DEFAULT_GOAL := help
.PHONY: help backend-build frontend-build build up down
## backend-build: 构建后端
backend-build:
@cd server && go build -o ../bin/server ./...
## frontend-build: 构建前端
frontend-build:
@cd web && npm run build
## build: 构建前后端
build: backend-build frontend-build
## up: 启动 docker-compose
up:
@docker compose up -d
## down: 停止并清理
down:
@docker compose down
## help: 显示帮助
help:
@echo "可用目标:"
@awk -F':.*## ' '/^[a-zA-Z0-9_-]+:.*## / {printf " %-16s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
通用「最佳骨架」总结
无论什么项目,一个好的 Makefile 应具备这几点:
.DEFAULT_GOAL := help—— 裸敲make永远安全- 变量集中在顶部 —— 名称、版本、flags 一目了然,便于覆盖
- 每个 target 配
##注释 —— 自动生成帮助 - 动作类目标全部
.PHONY—— 避免被同名文件干扰 - 保持「薄」 —— 复杂逻辑下沉到
scripts/,Makefile 只编排
💡 想快速复用,把上面的骨架存成模板文件,新项目
cp一份再改BIN/IMAGE即可。