Makefile для разработчиков — автоматизируйте задачи без использования «баш-спагети»
Make — это инструмент сборки 1977 года, который оказался отличным инструментом для выполнения задач. Один файл Makefile, make test, всё сделано — нет скриптов bash для поддержки, нет зависимостей для установки.
Вы знаете, как это происходит. Проект начинается чистым. Затем кто-то добавляет run.sh. Затем build.sh. Затем добавляется deploy.sh который подключает .env и вызывает первые два в определённом порядке, и вдруг появляются шесть файлов shell, которых никто не хочет трогать, и файл README, в котором написано «см. папку с скриптами».
Вносите исправления. Один Makefile в корне проекта, make test, выполнено.
Это не касается систем сборки на языке C. Make был создан до появления Linux и изначально разрабатывался для компиляции с использованием зависимостей — но его основная механика (именованные цели, выполняющие команды на уровне shell) делает его надёжным инструментом для выполнения задач в любой стеке. Node, Python, Go, Rust, Docker, что угодно, что вы создаёте.
Как работает Make на самом деле
Makefile — это список целей. Каждая цель имеет имя, необязательные зависимости и блок команд на shell:
.PHONY: build test lint clean
build:
npm run build
test:
npm test
Две вещи, которые мешают новичкам при первом знакомстве:
- Отступ должен быть настоящим символом табу, а не пробелами. Каждое редактор, который автоматически конвертирует табу, будет безусловно нарушать ваш Makefile, пока вы не настроите его иначе. Это было верно с 1977 года и Make никогда не простит вас за использование пробелов.
- По умолчанию, Make считает имена целей — именами файлов. Если в корне проекта есть файл
build,make buildничего не делает, потому что Make считает, что цель уже «создана». Решение —.PHONY.
Объявите каждую цель, которая не является реальным именем файла, как .PHONY. На практике, Makefiles, используемые как инструменты выполнения задач, объявляют каждую цель, потому что ни одна из них не создаёт файлы. Ваша .PHONY строка в итоге выглядит как первая строка шаблона ниже.
Переменные и переключатели из командной строки
Make имеет собственную синтаксис переменных — выглядит как в shell, но работает иначе:
DOCKER_IMAGE = myapp
TAG = latest
build:
docker build -t $(DOCKER_IMAGE):$(TAG) .
Переопределение из командной строки: make build TAG=v1.2.3. Не нужно редактировать файлы для версий сборки или развертываний в зависимости от среды. Доступны автоматически переменные среды shell — $(HOME), $(PATH), то, что находится в вашей среде при запуске make.
Готовый шаблон Makefile
Скопируйте это, удалите то, что не подходит, настройте команды под ваш стек:
.PHONY: install build test lint clean run docker-up docker-down help
# --- Config -------------------------------------------------------------------
DOCKER_COMPOSE = docker compose
APP_NAME = myapp
# --- Default target -----------------------------------------------------------
help:
@echo "Available targets:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " %-15s %s\n", $$1, $$2}'
# --- Dev ----------------------------------------------------------------------
install: ## Install dependencies
npm ci
run: ## Start the dev server
npm run dev
build: ## Build for production
npm run build
# --- Quality ------------------------------------------------------------------
lint: ## Run the linter
npm run lint
test: ## Run the test suite
npm test
test-watch: ## Run tests in watch mode
npm run test:watch
# --- Docker -------------------------------------------------------------------
docker-up: ## Start services via docker compose
$(DOCKER_COMPOSE) up -d
docker-down: ## Stop and remove containers
$(DOCKER_COMPOSE) down
docker-logs: ## Tail container logs
$(DOCKER_COMPOSE) logs -f
# --- Cleanup ------------------------------------------------------------------
clean: ## Remove build artifacts and caches
rm -rf dist node_modules/.cache .next
The help цель использует паттерн grep + awk для извлечения комментариев из текста и форматирования документации. Запустите ## и вы получите отсортированный список всех целей с их описаниями — без необходимости поддерживать отдельные документы. Это самый часто копируемый фрагмент в истории Makefile, и это объясняется. make help и вы получаете отсортированный список всех целевых элементов с их описаниями — не нужно хранить отдельные документы. Это самый часто копируемый фрагмент в истории Makefile, и это имеет причину.
Цепочка целей для CI
Make обрабатывает зависимости встроенно. Перечислите цели как зависимости, чтобы запускать их в порядке:
ci: lint test build ## Full CI check (lint -> test -> build)
make ci выполняет проверку, затем тестирование, затем сборку. Если какое-либо действие завершается с ненулевым кодом выхода, Make останавливается. Это корректное поведение CI — останавливаться громко, а не тихо скрывать ошибку шага.
Подавление отображения команд и выполнение многострочных команд
По умолчанию, Make выводит каждую команду перед её выполнением. Добавьте префикс @ для подавления:
setup:
@echo "Setting up project..."
@cp .env.example .env
@npm ci
@echo "Done."
Для команд, которые занимают несколько строк, соедините с помощью && — оно останавливается при ошибке, в отличие от точек, которые продолжают выполнение независимо:
migrate:
npm run db:migrate && \
npm run db:seed && \
echo "Migration complete"
Когда Make — неподходящий инструмент
Make поставляется с macOS (через Xcode Command Line Tools) и на всех дистрибутивах Linux. Нет необходимости в установке, нет конфликтов версий, минимальное сопротивление для большинства команд.
Где он не справляется:
- Окна — WSL работает хорошо, но на нативной Windows Make не работает без Chocolatey, Scoop или порта GnuWin32. Если ваша команда использует нативную Windows, просто — это близкий аналог, специально разработанный для этого пробела.
- Сложная логика — Make не является языком программирования. Условные операторы и циклы существуют, но они действительно ужасны. Если ваша логика сборки требует настоящего ветвления, напишите полноценный скрипт.
- Межплатформенные команды shell —
rm -rf,cpи другие Unix-инструменты не существуют на нативной Windows. Задача (на базе Go) решает эту проблему за счёт встроенной поддержки межплатформенных команд.
Для большинства команд на сервере и полных стеков на Mac или Linux, Make — это практичный стандарт. Он скучен, но это лучший способ — ничего не нужно устанавливать, ничего не нужно обновлять, ничего не ломается при обновлении зависимостей.
Поддержка чистого Makefile
Когда Makefile растёт в результате участия нескольких разработчиков и слияний, отступы и пробелы начинают отклоняться. Поскольку Make чувствителен к пробелам, одна лишняя пробела вместо таба молча нарушает цель без полезного сообщения об ошибке. IO Tools’ Makefile formatter нормализует отступы и удаляет лишние пробелы без изменения логики — полезно как проверка на чистоту до коммита.
Установите наши расширения
Добавьте инструменты ввода-вывода в свой любимый браузер для мгновенного доступа и более быстрого поиска
恵 Табло результатов прибыло!
Табло результатов — это интересный способ следить за вашими играми, все данные хранятся в вашем браузере. Скоро появятся новые функции!
Подписаться на новости
все Новые поступления
всеОбновлять: Наш последний инструмент был добавлен 8 июня 2026 года
