Использование Makefile в веб-разработке

Основное предназначение древней юниксовой утилиты make — сборка С/С++ программ.
Но в последнее время набирает популярность еще одно — запуск команд в проектах, особенно в веб-разработке.

Обычно в любом проекте требуется выполнять какие-то команды.
Например, из самого общего: запустить тесты, линтеры, веб-сервер.

Можно, конечно, просто записать их в документации, но её можно забыть обновить, да и неудобно всё время копировать или куда-то сохранять их на каждой машине (альясы, IDE, …).

Многие добавляют команды в систему сборки или конфиг менеджера пакетов, которые уже есть в проекте (Gulp/Grunt, npm, Composer, …). Но часто в проектах используется более одной такой системы (например, для backend и frontend) и команды оказываются в разных местах, потому что так проще по техническим причинам (например, не надо указывать полный путь к зависимости) или логичнее. Кроме того, в разных проектах используются разные технологии, и во всём этом легко запутаться.

Еще один вариант — скрипты на Bash или используемом в проекте языке (Python, JS, …). Более гибко, но сложнее писать и читать, и тоже зависит от используемых технологий, неудобно тащить в проект Питон только для этого.

Решение этих проблем — использовать Makefile в качестве сборника команд.
Создаем файл с именем Makefile в корне проекта, и добавляем туда любые используемые команды, в том числе и вызовы команд других систем сборки.

install:
	composer install
	npm install

setup: install
	cp -n .env.example .env || true

start:
	php -S localhost:8000 -t public

test:
	composer phpunit

lint:
	composer phpcs

deploy:
	git push heroku master

Теперь после git clone можно выполнить make setup для подготовки свежескаченного проекта к работе, make start для запуска веб-сервера, make lint test для запуска линтера и тестов, и make deploy для отправки изменений в продакшн.

Преимущества make:

  • Как правило всегда доступен на Linux и MacOS (установлен по умолчанию или ставится со стандартными инструментами разработки). Обычно веб-разработчики и сидят на этих ОС.
  • Не надо ставить ничего дополнительного для самого запуска команд. Например, интерпретатор и утилиты языка, чтобы просто запустить Docker или Vagrant уже содержащий всё нужное.
  • Не зависит от языка, фреймворка, IDE и прочих инструментов.
  • Простой синтаксис (для таких задач), проще и понятнее Bash-скриптов. Нельзя добавить сложную логику в сам Makefile, поэтому он не превратится в нечитаемую кашу. Не смешивается с другими вещами, в отличии от конфига менеджера пакетов.
  • Удобно вызывать: make вместо какого-нибудь npm run . Доступен автокомплит по TAB в стандартных терминалах.
  • Самодокументирование. Всегда можно открыть Makefile и посмотреть актуальные команды, узнать что можно делать в этом проекте.
  • Не надо вспоминать что и как запустить при переключении между разными языками/технологиями.
  • Стабильность. Мейку не первый десяток лет и вряд ли он поменяется.

Недостатки:

  • Недоступен на Windows. Можно взять make/nmake из MinGW/VS, но Windows не POSIX-совместимая ОС и некоторые команды из не-виндовых проектов не будут работать. Как вариант, WSL в вин10, Git Bash.
  • Некоторые особенности синтаксиса и работы. Отступы должны быть только TAB’ами, а команды совпадающие с именами папок/файлов надо добавить в .PHONY.

Примеры в проектах:

Больше инфы, краткое руководство с тонкостями и примерами:
https://makefile.site/
make-handbook/modern-make-handbook-ru.md at master · inem/make-handbook · GitHub
make-handbook/intro-ru.md at master · inem/make-handbook · GitHub