Make и make-файлы потеряны в прошлом для многих разработчиков, их преимущества теряются в потоке инструментов, которые постоянно изобретают колесо для создания программного обеспечения. Пора закончить эту сумасшедшую карусель.

Если вы спросите многих разработчиков о том, что в первую очередь приходит на ум, связанное с Make и make-файлами, вы, вероятно, получите несколько ответов: C / C ++, собственные проекты, огромные, архаичные или, возможно, даже старые. Некоторые молодые разработчики, выросшие в экосистеме JavaScript, возможно, даже не слышали о Make и не осознают преимуществ, которые они могут получить, используя существующий, хорошо зарекомендовавший себя и стабильный инструмент. Действительно ли нам нужно изучать новую программу выполнения задач или систему сборки каждые 18 месяцев, когда фреймворки JavaScript приходят и уходят?

Те, кто не понимает Unix, обречены изобретать его заново.

Подпись Usenet, ноябрь 1987 г.
- Генри Спенсер

При чем здесь современная разработка на JavaScript?

Сегодня нередко крупные проекты на основе JavaScript используют язык, который компилируется до JavaScript, либо для мощных языковых функций, либо для более строгой проверки типов. Мы используем Browserify, чтобы упаковать все наши модули JavaScript вместе в пакет, чтобы позволить разработчикам интерфейсов иметь более основанный на композиции опыт разработки с помощью модулей (как внутренние разработчики в Node.js). Мы используем LESS или SASS и компилируем в CSS, который может понять браузер. Мы минимизируем наш JavaScript, чтобы файлы были меньше, что приводит к более быстрой загрузке и времени загрузки страницы.

Что у всего этого общего? По сути, каждый из них берет набор входных файлов и преобразует их в набор выходных файлов. И именно в этом Make невероятно хорош.

Что делают make-файлы? Make-файлы - это просто декларативный способ преобразования одного файла (или серии файлов) в другой. Вот и все, это так просто. Это не относится к C, C ++ или даже к языкам программирования. С таким же успехом вы можете использовать make-файл для преобразования документации по разметке в поставляемые HTML-файлы, или для упаковки важных файлов в архив zip / tar, или для выполнения множества других преобразований.

Благодаря декларативному характеру и реализации Make может использовать make-файлы только для выполнения простых преобразований, необходимых для достижения конечного формата назначения. Если исходный файл не изменился с момента последнего преобразования, исходный файл не нужно обрабатывать повторно. В более крупных проектах это огромная выгода для скорости и благо для разработчиков.

Make впервые появился более 40 лет назад, и с тех пор с его помощью было создано множество программного обеспечения. Это проверенное и стабильное программное обеспечение, которое отлично выполняет то, для чего оно предназначено: преобразование файлов из исходного формата в целевой формат с очень простым и понятным механизмом объявления зависимостей. Он основан на тексте, не пытается решить все самостоятельно и обладает отличным опытом интеграции посредством вызова сценариев оболочки. Другими словами, он очень похож на Unix. В этом нет ничего удивительного, учитывая, что он зародился в среде Unix.

Некоторые разработчики имели опыт работы с очень сложными и запутанными make-файлами в более крупных проектах. Но так быть не должно. Фактически, создать пакет NPM, реализованный в Typescript (от создания исходного кода до упаковки пакета NPM), может быть довольно просто:

Да, приведенный выше пример был для создания очень небольшого проекта. Но то, что проект становится больше, не означает, что пользовательский опыт в Make ухудшается. Давайте посмотрим на пример.

На работе я сейчас работаю над более крупным проектом, основанным на AWS Kinesis и Lambda Functions, бессерверной архитектуре системы потоковой обработки. «Сервис» для удобства основан на одном репозитории git. Но нам нужны легкодоступные общие библиотеки между нашими различными обработчиками Lambda, которые также могут быть независимо развернуты в проектах. Это делает развертывание исправлений или новых функций в производственной среде намного быстрее и с гораздо меньшими накладными расходами, чем развертывание всей службы как одного большого монолита.

Структура нашего проекта вдохновлена ​​сообщением StrongLoop о создании модульной структуры проекта Node.js. Несмотря на то, что мы используем TypeScript, эта структура определенно применима к нам. Итак, мы начали с подхода к созданию ссылок и сценариев npm, описанному в сообщении в блоге.

Структура нашего проекта в итоге выглядела примерно так:

Но по мере роста количества модулей и появления различного порядка зависимостей (как это происходит в более крупном программном обеспечении Enterprise) этот подход быстро стал громоздким и болезненным. Мы обнаружили, что у нас есть целый набор сценариев до установки, после установки и до запуска. Было очень сложно понять, что происходило во время сборки для начальной загрузки службы. А интеграция новых подпроектов была проблемой. Это также был тип решения «строить все или ничего», без необходимости выполнять нетривиальный объем дополнительной работы.

Прежде чем брать с полки новейшие разработки, такие как Gulp, мы решили взглянуть на то, что Make может сделать для этого, поскольку это хорошо зарекомендовавший себя инструмент, и он находится прямо на его пути. Это решение послужило толчком к моему растущему признанию Make (и вдохновило меня на создание этого сообщения в блоге).

Поскольку мы представляли собой более крупный и растущий проект, мы, естественно, беспокоились о том, будет ли масштабироваться наше решение для сборки. Я думаю, что с помощью Make определенно так и будет. И, кроме причуд Make, к которым вы привыкаете после того, как некоторое время впервые ее используете, я думаю, что младший разработчик мог бы интегрировать свои собственные библиотеки в этот процесс Make.

Вот как будет выглядеть потенциальный make-файл для вышеуказанного проекта:

Как видите, это не должно быть очень сложно. Поскольку это серверная служба, у нас нет функции просмотра, уменьшения или минификации. Но это должно помочь нарисовать картину, что даже с этими дополнениями все должно быть довольно простым.

Если вы вносите изменения в библиотеку baz, перестраивается только baz и только baz переустанавливается в подпроект обработчика omega. Добавьте в этот процесс наблюдателя (например, сценарий npm, например watch ‘npm run build’ src — wait=5), и ваш процесс сборки станет более насыщенным и улучшит локальную разработку.

Плюсы

Что мне действительно нравится в этом, так это то, что все запускается только в случае необходимости. Чтобы это стало возможным, вам даже не нужен инкрементный компилятор. Если исходные файлы не были обновлены, нет необходимости повторно создавать целевые файлы. Make знает это, сравнивая время последнего изменения исходных файлов и целевых файлов. Вы можете увидеть простую интеграцию с существующими инструментами, такими как tsc и npm. Мне не нужно было ждать, пока будет создана оболочка (или чтобы создать свою собственную оболочку) в инструменте сборки на основе кода.

Еще одно менее очевидное преимущество при сравнении Make с инструментами сборки на основе кода, такими как Grunt или Gulp, - это декларативность по сравнению с императивом. Вы можете сосредоточиться на конечном результате (объявив что нужно сделать) вместо того, чтобы сосредоточиться на том, как выполняется фактическая работа.

Make также является автономным инструментом, поэтому нет необходимости вводить кучу других зависимостей кода, как это делают средства выполнения задач на основе кода. Это не только улучшает взаимодействие с пользователем, но также означает, что у программного обеспечения меньше возможностей сломаться (например, новая версия зависимости, которая нарушает функциональность основного инструмента).

Обратные стороны

Да, это еще один инструмент и язык, который нужно изучить разработчикам. Но это то, за что нам, как разработчикам, платят, не так ли? Нам всегда нужно изучать новые инструменты и методы (или переучивать старые инструменты и техники в данном случае: P). Мы принимаем этот постоянно развивающийся опыт, поскольку новейшие и лучшие языки программирования или библиотеки программного обеспечения выпускаются каждый месяц.

Но помните, что в этом случае мы изучаем общий инструмент, который мы будем использовать разными способами в течение долгого времени. Альтону Брауну не о чем беспокоиться, этот инструмент очень многозадачный. Make существует уже более 40 лет и в ближайшее время никуда не денется. Можем ли мы сказать то же самое о Grunt, Gulp или следующем выпуске Task Runner du jour?

Исторически сложившейся проблемой использования Make было отсутствие достойной поддержки в Windows. Используя Make, вы потенциально усложняли жизнь всем своим пользователям Windows. Для многих проектов это не было стартом. Но с недавним добавлением поддержки Linux в Windows и продолжающимся изменением взглядов под руководством Сатьи Наделлы в Microsoft, мы надеемся, что это беспокойство осталось в прошлом. Я считаю, что эта тенденция является большим подспорьем для разработчиков программного обеспечения, учитывая все замечательные вещи, которые можно извлечь из Linux и использовать в ней.

Сейчас отличное время, чтобы изучить Make

Итак, сегодня отличное время, чтобы изучить и начать использовать Make и make-файлы. Они по-прежнему очень важны для нашей сегодняшней работы как разработчиков. Нет необходимости в постоянно открывающейся двери бегунов в дневное время. Не поддавайтесь беговой дорожке с инструментами для сборки и не сжигайте себя. Изучите мощный инструмент, которым вы сможете пользоваться долгое время, и в ближайшее время никуда не денется.

Да, пора вернуться к Makefiles! Давай сделаем это!

P.S. Если у вас большой опыт работы с Make / makefile и вы видите, как можно улучшить приведенные выше скрипты, не стесняйтесь оставлять комментарии. Я все еще считаю себя новичком в Make.

Пора вернуть файлы Makefile изначально было опубликовано на сайте Coding Coda.