正在加载,请稍候…

现代开发的 Makefile:任务自动化与项目管理

掌握 Makefile 实现项目自动化。学习变量、模式规则、伪目标、并行执行,并通过 make 命令组织开发工作流。

现代开发的 Makefile:任务自动化与项目管理

现代开发的 Makefile

项目结构 Makefile

# Makefile
.PHONY: all install dev build test lint clean deploy help

# Default target
.DEFAULT_GOAL := help

# Variables
APP_NAME := myapp
VERSION := $(shell git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0")
COMMIT := $(shell git rev-parse --short HEAD)
BUILD_TIME := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")

# Docker
IMAGE := ghcr.io/myorg/$(APP_NAME)
REGISTRY := ghcr.io

# Colors
GREEN := \033[0;32m
NC := \033[0m

##@ Development

install: ## 安装依赖
    npm ci

dev: ## 启动开发服务器
    npm run dev

build: ## 构建生产版本
    npm run build

type-check: ## 运行 TypeScript 类型检查
    npx tsc --noEmit

##@ Testing

test: ## 运行测试
    npm test

test-watch: ## 以监视模式运行测试
    npm test -- --watch

test-coverage: ## 运行测试并生成覆盖率
    npm test -- --coverage

lint: ## 运行代码检查
    npm run lint

lint-fix: ## 修复代码检查错误
    npm run lint -- --fix

##@ Docker

docker-build: ## 构建 Docker 镜像
    docker build \
        --build-arg VERSION=$(VERSION) \
        --build-arg COMMIT=$(COMMIT) \
        --build-arg BUILD_TIME=$(BUILD_TIME) \
        -t $(IMAGE):$(VERSION) \
        -t $(IMAGE):latest \
        .

docker-push: docker-build ## 构建并推送 Docker 镜像
    docker push $(IMAGE):$(VERSION)
    docker push $(IMAGE):latest

docker-run: ## 本地运行 Docker 容器
    docker run --rm -p 3000:3000 --env-file .env $(IMAGE):latest

##@ Deployment

deploy-staging: docker-push ## 部署到预发布环境
    kubectl set image deployment/$(APP_NAME) $(APP_NAME)=$(IMAGE):$(VERSION) -n staging
    kubectl rollout status deployment/$(APP_NAME) -n staging

deploy-prod: docker-push ## 部署到生产环境(需要确认)
    @echo "Deploying $(VERSION) to production..."
    @read -p "Are you sure? [y/N] " confirm && [ "$confirm" = "y" ]
    kubectl set image deployment/$(APP_NAME) $(APP_NAME)=$(IMAGE):$(VERSION) -n production

##@ Utilities

clean: ## 清理构建产物
    rm -rf dist build .next coverage node_modules/.cache

setup: install ## 完整项目设置
    cp -n .env.example .env || true
    @echo "$(GREEN)Setup complete! Edit .env with your credentials.$(NC)"

db-migrate: ## 运行数据库迁移
    npx prisma migrate deploy

db-reset: ## 重置开发数据库
    npx prisma migrate reset --force

##@ Help

help: ## 显示此帮助信息
    @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \\033[36m<target>\\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf "  \\033[36m%-20s\\033[0m %s\n", $1, $2 } /^##@/ { printf "\n\\033[1m%s\\033[0m\n", substr($0, 5) }' $(MAKEFILE_LIST)

现代开发的 Makefile:任务自动化与项目管理 插图

模式规则与函数

# Pattern rule - compile all .ts files
BUILD_DIR := dist
SRC_DIR := src

TS_FILES := $(shell find $(SRC_DIR) -name '*.ts')
JS_FILES := $(TS_FILES:$(SRC_DIR)/%.ts=$(BUILD_DIR)/%.js)

$(BUILD_DIR)/%.js: $(SRC_DIR)/%.ts
    npx tsc --outDir $(BUILD_DIR) 
lt; # Use functions FILES := $(wildcard src/**/*.ts) BASENAME := $(notdir $(FILES)) DIRS := $(sort $(dir $(FILES))) # String functions UPPER_NAME := $(shell echo $(APP_NAME) | tr a-z A-Z) TRIMMED := $(strip $(FILES))

现代开发的 Makefile:任务自动化与项目管理 插图

并行执行

# Run tests and linting in parallel
ci: 
    $(MAKE) -j2 test lint

# Parallel builds
build-all:
    $(MAKE) -j4 \
        build-frontend \
        build-backend \
        build-worker \
        build-scheduler

现代开发的 Makefile:任务自动化与项目管理 插图

条件逻辑

# Platform detection
UNAME := $(shell uname -s)
ifeq ($(UNAME), Darwin)
    OPEN := open
    SED := gsed
else
    OPEN := xdg-open
    SED := sed
endif

# Environment-based config
ENV ?= development

ifeq ($(ENV), production)
    DOCKER_FLAGS := --no-cache
    NODE_FLAGS := --max-old-space-size=4096
else
    DOCKER_FLAGS :=
    NODE_FLAGS :=
endif

# Check for required tools
check-tools:
    @which docker > /dev/null || (echo "Docker not found" && exit 1)
    @which kubectl > /dev/null || (echo "kubectl not found" && exit 1)
    @which node > /dev/null || (echo "Node.js not found" && exit 1)
    @echo "All required tools found"

Makefile 最佳实践

实践 原因
.PHONY 目标 不与文件冲突
## 注释 make help 中显示
默认目标 清晰的入口点
检查依赖 缺失时尽早失败
并行标志 更快的构建