Как сделать свою сборку
Перейти к содержимому

Как сделать свою сборку

  • автор:

 

Как сделать свою сборку

На первом шаге проект нужно сконфигурировать, то есть создать финальный скрипт сборки, запустив cmake <параметры> <путь-к-каталогу> в будущем каталоге сборки.

На втором шаге нужно запустить финальный скрипт. Не вызывайте make ! Утилита cmake сделает это сама:

Структура CMakeLists.txt

В начале главного файла CMakeLists.txt ставят метаинформацию о минимальной версии CMake и названии проекта:

Затем следует список инструкций, служащих для вычисления различных переменных, создания целей сборки, подключения проектов из подкаталогов и так далее. Например, подключить дополнительный CMakeLists.txt из подкаталога можно так:

Целью может стать исполняемый файл, собираемый из исходного кода

Целью также может быть библиотека, статическая или динамическая.

Автогенерация проекта для Visual Studio (Windows)

Если используется Visual C++, то путь немного другой: на шаге конфигурирования создаётся проект для Visual Studio, который затем можно собрать из IDE либо так же из командной строки.

Созданный проект Visual Studio нельзя изменять и использовать постоянно, потому что при генерации проекта используются абсолютные пути и другие неприемлемые для постоянной работы вещи.

Если проект был сконфигурирован успешно, то в каталоге ../myapp-build появятся автоматически сгенерированный BUILD_ALL.sln и проекты для Visual Studio. Их можно открыть к IDE, либо собрать из командной строки с помощью cmake. Названия опций говорят сами за себя:

Зависимости между библиотеками и приложениями

Не используйте директивы include_directories , add_definitions , add_compile_options ! Они меняют глобальные настройки для всех целей, это создаёт проблемы при масштабировании.

  • Используйте target_link_libraries для добавления статических и динамических библиотек, от которых зависит цель
  • Используйте target_include_directories вместо include_directories для добавления путей поиска заголовков, от которых зависит цель
  • Используйте target_compile_definitions вместо add_definitions для добавления макросов, с которыми собирается цель
  • Используйте target_compile_options для добавления специфичных флагов компилятора, с которыми собирается цель

Вы можете выбирать область видимости настройки:

  • PUBLIC делает настройку видимой для текущей цели и для всех зависящих от неё целей
  • PRIVATE делает настройку видимой только для текущей цели
  • INTERFACE делает настройку видимой только для всех зависящих от неё целей

Пример использования областей видимости:

Схема зависимостей условного проекта:

Схема

Выбор стандарта и диалекта C++

Для настройки стандарта и флагов языка C++ не добавляйте флаги напрямую!

В CMake версии 3.8+ вы можете прямо потребовать включить нужный стандарт:

В CMake версии до 3.7 включительно можно использовать set_target_properties (если не работает, то у вас слишком старый CMake):

Для разработчиков библиотек есть более тонкий контроль над возможностями языка:

Функции в CMake

CMake позволяет объявлять функции командами function(name) / endfunction() и макросы командами macro(name) / endmacro() . Предпочитайте функции, а не макросы, т.к. у функций есть своя область видимости переменных, а у макросов — нет.

Добавление исходников к цели с target_sources

Лучше добавлять специфичные исходники с помощью target_sources, а не с помощью дополнительных переменных.

Интерфейс к утилитам командной строки

Функция find_package

Функция find_package принимает имя библиотеки как аргумент и обращается к CMake, чтобы найти скрипт для настройки переменных данной библиотеки. В итоге при сборке либо возникает ошибка из-за того что пакет не найден, либо добавляются переменные, хранящие пути поиска заголовков, имена библиотек для компоновщика и другие параметры.

Пример подключения Boost, вызывающего встроенный в CMake скрипт FindBoost:

Пример подключения библиотеки Bullet с помощью встроенного скрипта FindBullet и компоновки с приложением my_app:

Как сделать свою сборку в Dota 2, свой билд в доте 2

Всем привет, дорогие читатели. Сегодня мы поговорим о том, как создать свою сборку предметов в Dota 2. И, как обычно, мы сделаем это на максимально высоком уровне, подробно, четко и полностью раскрыв всю необходимую информацию.

Кстати, все гайды на эту тему – будут отправлять вас делать сборку на сторонний сайт по Доте. Это очень неудобно, к тому же – все сборки там – старые, и относятся к предыдущим патчам. Мы же – научим вас делать собственную сборку прямо в игре, причем – в любом патче, в любой мете.

Для чего нужно создавать свою сборку в Доте

Собственная сборка нужна для того, чтобы во время матча – вы не искали предмет, какой хотите купить. Вообще, Dota 2 – игра довольно-таки ситуативная, и предметы в ней нужно покупать, в зависимости от той или иной ситуации. Но, сыграв какую-то 1000 игр на одном герое – вы и сами сможете учить игру, что надо делать. Естественно, за такое количество игр – вы выучите героя вдоль и поперек, а вместе с этим и предметы, которые ему заходят лучше всего. А раз так – просто создайте свою сборку, и вы сэкономите несколько минут, на протяжении всей игры, на поиск нужных предметов.

Как создать свою сборку в Dota 2

Первое, что вам нужно будет сделать – это зайти в главное меню Доты и выбрать пункт «герои».

Выбираете героя, на котором собираетесь создавать собственную сборку. Например – Визажа.

Как сделать свою сборку в дота 2

Кликнув на Визаже, вы перейдете в меню, показанное выше. Обратите внимание на руководства. Прямоугольник на черном фоне – это все доступные собственные сборки игроков. Кстати, тут же вы сможете посмотреть и винрейт этих сборок, а значит и определить их полезность.

Как создать свой сборник программ?

Всем привет, сегодня я хочу рассказать вам о том, как вы можете создать свой собственный сборник программ. Многие думают, что сделать это сложно, но на самом деле это не так. Сегодня я покажу два способа как вы можете создать свой сборник программ. Первый способ с помощью MinstAll он будет более легкий, а второй способ это с помощью WPI.

создай свой WPI

Создаем свою сборку программ с помощью программы MinstAll

Скачиваем программу тут. Распаковываем и запускаем программу с помощью файла autorun.exe. У вас откроется сама программа, в которой вы сможете добавлять те приложения, которые вам необходимы. Чтобы добавить программу нажмите на кнопку настроек, которая находится в верхнем правом углу. Нажмите на зелёный + который находятся рядом. Выберите файл, который Вы будете использовать как установщик какой-либо программой, этот файл может лежать вас на флешке, диске либо на вашем компьютере, без разницы, вы его выбираете там, где он у вас лежит.

Но лучшим вариантом если вы поместите данную программку в раздел minstall/software. Выбрали файл, нажимали кнопку открыть, в следующем окне Вам нужно будет прописать: название программы, версию программы, уникальный идентификатор guid, если есть программы которые исключают установку данной программы, то их нужно добавить, если есть программы которые включают данную установку, то их тоже нужно добавить, нужно указать статус программы. Далее вы представляете галочки всех совместимых операционных систем, если подходят все операционные системы, то можно просто поставить галочку все. Также вы можете выбрать битность данной программы на какую битность её можно будет установить.

Путь приложению программа добавить сама если вы поместите программу как я говорил в начале в папку software. Чтобы Вы могли легко определить программу на глаз можете добавить иконку. Иконку Вы можете выбрать откуда угодно она сама автоматически подтянется в нужную папку. Если вы хотите запустить программу в скрытом виде, то там есть специальную галочку, если для программы нужна перезагрузка можно поставить галочку перезагрузить ОС. Ну и последнее что необходимо это указать ключи запуска если у вас репак программы либо если вы хотите указать какие-то определенные настройки для того, чтобы эти настройки включились в момент установки.

Есть стандартные ключи запуска, которые можно посмотреть в самой программе, а некоторые ключи придется поискать в Интернете или спросить на сайте у разработчика программы, разные упаковщики exe файлов имеют разные ключи запуска. Программка которая покажет возможные ключи тут.

Более подробно о том, как создать свой набор программ Вы можете посмотреть в моём видео.

Создаем сборник программ с помощью WPI

С WPI всё будет немного сложнее. Рекомендую почитать всю документацию по созданию WPI от разработчика. Там будет даже та информация, которую я, возможно, забуду упомянуть.

Для начала Вам нужно будет скачать чей-то WPI, я расскажу на примере своего WPI. Скачайте его. Чтобы можно было подключить доступ к конфигурации самого WPI, Вам необходимо распаковать файлы, которые находятся в образе, который вы скачали, на жесткий диск или флешку.

Зайдите в папку WPI и запустите файл WPI.EXE. Чтобы добавить или удалить какую-либо программу из WPI, Вам необходимо нажать на кнопку конфигурация программ. У вас откроется мастер конфигурация. В самом верху будут кнопки добавить, клонировать и удалить, с помощью этих кнопок Вы можете добавить новую программу, клонировать уже существующую и удалить ту которая вам не нужна.

Если вы скачали чью-то сборку, то у вас уже будет определенный набор утилит часть из них вы можете удалить, а потом добавить свои программы. Всё очень похоже с MinstAll.

Вам нужно будет дать название программы, короткое описание, категорию если у вас программы разбиты на различные категории, уникальный ID, есть настройки, которые позволяют установить программу по умолчанию, принудительно или активировать именно 64-битный процесс. Если для программы требуется перезагрузка, можно сделать отметку для этого.

Далее вам нужно будет перейти во вкладку команда, в данной вкладке Вам нужно будет прописать путь к вашей программе, которая будет находиться в корне вашей WPI и ключи запуска, если они есть. Есть дополнительные вкладки, которые помогут вам прописать всё необходимое для вашей программы пути и возможных различных настроек.

На вкладке зависимости Вы можете включить зависимость от какой-либо другой программы либо исключить зависимость от какой-либо другой программы, тут вы уже смотрите что у вас за программа Нужны ли ей какие-то другие дополнительные установки, например дополнительное ПО.

Во вкладке tooltips, вы можете создать описание программы, я добавить иконку программы.

После того как Вы заполните все вкладки ВВП я, я Вам нужно будет нажать кнопку сохранить чтобы всё то что вы прописали было сохранено для вашей программы. При внесение каких-либо изменений в другие программы Вы должны нажимать сохранить каждый раз. Более подробно по поводу настройки Вы можете посмотреть в моём видео выше.

Надеюсь, теперь вы знаете, как вы можете легко создать свой сборник программ, на основе minstall и WPI. Если вы знаете что-то ещё, чего я не рассказал в этом тексте и не показал видео, пишите об этом в комментариях, думаю другим будет очень интересно.

Как я сделал свою сборку Gulp для быстрой, лёгкой и приятной вёрстки

Серьёзно и профессионально я начал заниматься вёрсткой в 2019 году, хотя до этого ещё со школы интересовался данной темой как любитель. Поэтому новичком мне себя назвать сложно, но и профессионалом с опытом 5+ лет я тоже не являюсь. Тем не менее, я успел познакомиться со сборщиком Gulp, его плагинами и сделал для себя хорошую, как по мне, сборку для работы. О её возможностях сегодня и расскажу.

ВАЖНО! В этой статье речь пойдёт о самой последней версии сборки. Если вы пользуетесь версиями сборки, вышедшими до публикации этой статьи, информация будет для вас не релевантна, но полезна.

Какие задачи решает эта сборка?

вёрстка компонентами (вам не нужно в каждую страницу копировать head, header, footer и другие повторяющиеся элементы, вплоть до кнопок или кастомных чекбоксов);

вёрстка с препроцессорами (SASS/SCSS);

конвертация шрифтов из ttf в eot, woff, woff2;

лёгкое (почти автоматическое) подключение шрифтов;

лёгкое (почти автоматическое) создание псевдоэлементов-иконок;

обработка изображений «на лету»;

минификация html/css/js файлов;

возможность вёрстки с использованием php;

выгрузка файлов на хостинг по FTP;

несколько мелких задач с помощью миксинов.

Собственно создание сборки

Начнём собирать нашу сборку (простите за тавтологию). Предварительно нам потребуется уже установленная на компьютере LTS-версия Node.js и NPM (входит в пакет Node.js) либо Yarn. Для нашей задачи не имеет значения, какой из этих пакетных менеджеров использовать, однако я буду объяснять на примере NPM, соответственно, для Yarn вам потребуется нагуглить аналоги NPM-команд.

Первое, что нам нужно сделать — это инициализировать проект. Открываем директорию проекта в командной строке (очень надеюсь, вы знаете, как это делается) и вводим команду npm init.

После этого npm задаст нам несколько стандартных вопросов по типу названия проекта, автора, версии и т.д. Отвечаем на них как душе угодно. Для нашей задачи это не имеет никакого значения.

Далее будет намного удобнее работать через Visual Studio Code (поскольку у него есть встроенный терминал) или любой другой удобный вам редактор + терминал.

Прежде всего, нам нужно установить сам Gulp. Делается это двумя командами npm i gulp -global — устанавливаем Gulp глобально на систему и npm i gulp —save-dev — устанавливаем Gulp локально в проект. Ключ —save здесь отвечает за сохранение версии плагина при дальнейшей установке (без него вам может установить более новую, несовместимую с другими плагинами версию), а ключ -dev указывает на то, что этот пакет необходим только во время разработки проекта, а не во время его выполнения. Например, если мы устанавливаем в проект пакет Swiper, который содержит скрипты слайдера и будет отображаться на странице, мы будем устанавливать его без ключа -dev , поскольку он нужен для выполнения, а не для разработки.

После того, как Gulp установился, имеет смысл создать в корне проекта управляющий файл gulpfile.js, в котором мы и будем писать задачи для сборщика.

После этого нам нужно подключить Gulp в нашем файле, для того чтобы он исполнялся. Это делается с помощью require:

Далее, для каждой задачи будем использовать модули в отдельных файлах. Для того, чтобы не подключать каждый модуль отдельно, нужно установить и подключить плагин require-dir. Устанавливается он всё той же командой (как и все последующие плагины, поэтому далее повторяться не буду, просто знайте, что установить — это npm i $PLUGIN-NAME$ —save-dev ). После установки подключаем его и прописываем путь к директории, в которую будем складывать модули (у меня это директория tasks):

Первая задача

Давайте проверим, всё ли мы правильно сделали. Создадим в директории tasks файл модуля с именем hello.js. В созданном файле напишем простейшую функцию, которая будет выводить в консоль строку «Hello Gulp!» (можете придумать что-то менее банальное, если хотите).

Теперь вернёмся в gulpfile.js и зададим там задачу hello:

Теперь командой gulp hello в терминале запустим нашу задачу. Если всё сделано правильно — в терминал должно вывестись приблизительно такое сообщение:

Так же, можно получить список всех заданных задач командой gulp —tasks .

Файловая структура

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

В директории src/ нам понадобятся следующие поддиректории:

components/ — директория для компонентов

components/bem-blocks/ — директория для БЭМ-блоков

components/page-blocks/ — директория для типовых блоков страницы, таких как хедер, футер и т.п.

fonts/ — директория для шрифтов

img/ — директория для изображений

js/ — директория для файлов JavaScript

scss/ — директория для файлов стилей

scss/base/ — директория для базовых стилей, которые мы изменять не будем

svg/ — директория для файлов SVG

svg/css/ — директория для SVG-файлов, которые будут интегрироваться в CSS

Получиться в итоге должно приблизительно следующее:

ВАЖНО: в пустых директориях, таких как img/ , fonts/ и т.п. перед тем как пушить в удалённый репозиторий (например на Github) нужно создать пустые файлы с именем .gitkeep. Это нужно для того, чтобы Github не удалил пустые директории из сборки.

Добавление задач и настройка плагинов

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

Задачи стилей

Для работы с scss нам нужно будет установить некоторые плагины, которые будут обрабатывать и компилировать наш scss код в готовый css. Прежде всего, установим сам плагин Gulp-sass, который будет компилировать scss файлы в обычный css, понятный браузеру. Так же, для того, чтобы scss-файлы можно было импортировать не по одному, а целыми директориями нам понадобится gulp-sass-bulk-importer, для автоматической расстановки префиксов — gulp-autoprefixer, для очистки лишнего css — gulp-clean-css и для конкатинации («склеивания» файлов вместе) — gulp-concat. Так же, для того, чтобы в DevTools было понятно, из какого файла взялись стили, установим gulp-sourcemaps. Можно каждый раз не прописывать команду npm i в терминале, а указать перечень устанавливаемых плагинов через пробел, но ключи тогда нужно будет указать перед названиями плагинов: npm i —save-dev gulp-sass gulp-sass-bulk-importer gulp-autoprefixer gulp-clean-css gulp-concat gulp-sourcemaps

Теперь создадим в директории tasks/ файл модуля, в котором опишем, что нужно делать галпу с scss-файлами. От gulp нам понадобятся src и dest, а остальные плагины подключим полностью:

Далее экспортируем функцию:

В ней-то мы и будем обрабатывать наши scss файлы. Gulp выполняет последовательность действий .pipe над объектами, указанными в модуле src . Это похоже на конвейер, проходя по которому, код или файлы, которые мы создали в директории src/, превращаются в то, что мы хотим видеть в итоге и складываются в директорию build/.

Давайте определим порядок действий:

Взять файлы scss из директорий scss/

Инициализировать карту исходных файлов (sourcepams)

Скомпилировать в css

Расставить вендорные префиксы

Очистить от лишнего

Склеить в единый файл style.css

Записать карту исходных файлов в получившемся файле

Положить его в build

Итогом (return) нашей функции как раз и будет результат всей последовательности действий, которые мы определили. Это и запишем:

Пояснение каждой строки кода отдельно

src(‘src/scss/**/*.scss’) — определяем источник исходного кода (source)

.pipe(map.init()) — инициализируем маппинг, чтобы он отслеживал включаемые файлы

.pipe(bulk()) — проводим код через плагин, который ползволяет использовать директиву @include в scss для директорий, а не только для отдельных файлов

.pipe(sass()) — проводим код через сам компиллятор sass

.pipe(prefixer()) — проводим код через префиксер, который расставит вендорные префиксы

.pipe(clean()) — проводим код через «очиститель» от лишнего css

.pipe(concat(‘style.min.css’)) — склеиваем все исходные файлы в один

.pipe(map.write(‘../sourcemaps/’)) — записываем «карту» источников полученного файла

.pipe(dest(‘build/css/’)) — кладём итоговый файл в директорию

Единственное, чего нам здесь не хватает — настроек и методов для некоторых плагинов. Настройки для плагинов задаются в виде объектов, которые передаются аргументом в функцию плагина. Звучит страшно, а на деле выглядит примерно так: .pipe(sass() . Для sass я определяю степень сжатия выходного css как compressed, а так же добавляю на событие error логирование ошибки, чтобы было понятно, что не так (если вдруг). И того получаем такой пайп:

Для автопрефиксера возьму рекомендованые в документации параметры. Для того, чтобы задать свои значения настроек — переходите к документации каждого плагина и читайте, за что отвечает та или иная опция.

С клинером вообще всё просто: выставляю уровень очистки (level) в значение 2 и готово.

Что такое bs и для чего он нужен я опишу ниже, в соответствующем разделе.

Как итог, в файле tasks/style.js у нас будет следующее:

 

Приблизитекльно аналогичным образом поступаем со стилями библиотек и плагинов, которые будем подключать к будущим проектам. Создаём константу plugins, в которой у нас будет массив файлов-источников из node_modules const plugins = []; . Путь к файлам стилей будем писать в кавычках через запятую — получится массив строк с путями к файлам плагинов. Подключаем в файл gulp.src и gulp.dest, плагины gulp-concat и gulp-sourcemaps аналогично предыдущей задаче и прописываем наш «конвейер»:

Взять файлы из источников (в данном случае — из константы)

Прогнать всё через sass

Подчистить неиспользуемый css (в библиотеках это особенно важно)

Сконкатенировать файлы в один

Сложить в директорию build/css

Но тут есть одна особенность — добавим условие, если длина массива plugins будет равна нулю — эта функция и вернёт коллбэк done() , который просто выдаст сообщение в терминал, что плагинов нет без выполнения других действий. Без этого, наша функция будет ругаться на отсутствие плагинов. А они нужны далеко не всегда.

А так же нам понадобится плагин chalk для раскрашивания сообщения в консоли, чтобы мы обратили на неё внимание. Принципиально этот плагин не будет влиять на работу задачи, только разукрашивать консоль, примерно так:

В результате, файл tasks/libs_style.js будет выглядеть так:

Задачи для JavaScript

C JavaScript всё будет немного сложнее. Для разработки нам понадобится чистый, не редактированный и не минимизированный код. При этом, в готовом проекте мы будем прогонять код через babel, который не только приводит код к стандарту ES5, но и скоращает его, путём замены имён переменных и функций на более короткие (одно-двух символьные). Поэтому, нам потребуется три разные задачи: для нашего JS-кода, для плагинов/библиотек и для билда.

Для обработки JS нам понадобится gulp-uglify-es — для минификации JS-кода и gulp-babel для оптимизации. С остальными плагинами, которыми мы будем обрабатывать наш код вы уже знакомы.

Для начала, опишем процесс работы с кодом:

Определить источники (sources)

Склеить в один файл

Минифицировать полученны файл

Записать источники в файл

Положить итоговый файл в build/js/

Для итоговой (билдовой) версии после 4 пункта мы ещё прогоним его через babel для оптимизации. И для этого нам понадобится установить @babel/core , а так же @babel/preset-env. После установки, в корне проекта нужно будет создать файл .babelrc , который указывает на пресет настроек Babel со следующим содержимым:

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

Как видим, тут есть указанный напрямую файл src/js/01_main.js который должен присутствовать для выполнения задач, поэтому создадим его в директории src/js .

Так же стоит отметить ещё пару мелких особенностей. Во-первых, как видите, подключение плагина gulp-uglify-es я сделал сразу с параметром (свойством) default: const uglify = require(‘gulp-uglify-es’).default — указание какого-либо параметра обязательно для успешной работы плагина. Я использую стандартную настройку. Вы-же можете порыться в документации к плагину и использовать другие настройки, если хотите. Во-вторых, в build-задаче я не использовал sourcemaps, поскольку они там и не нужны. Эта карта необходима при разработке, чтобы видеть источники кода в итоговом файле.

Задачи для HTML/PHP

Следующим этапом будет обработка HTML или PHP, в зависимости от того, на чём вы пишете. Мы не будем рассматривать препроцессоры, такие как Pug или Nunjucks по той простой причине, что с появлением Emmet они перестали значительно ускорять процесс разработки на HTML, а шаблоны мы вполне можем строить другим плагином: gulp-file-include, который умеет, как мне кажется, нечто большее — включать текстовое представление любых файлов в любые файлы. Далее, вы поймёте, почему я считаю это важным. Для разработки на PHP это вообще не имеет никакого значения. Там можно использовать require и другие возможности PHP из коробки. Если же вы привыкли пользоваться препроцессорами — вы легко сможете настроить Gulp для их обработки, я считаю.

Для минификации HTML можно использовать gulp-htmlmin, добавив его в виде .pipe(htmlmin(< collapseWhitespace: true >)) в свою задачу html. Однако, как показывает практика, вёрстка — не конечный этап разработки в 90% случаев, поэтому добавлять его в сборку я не буду. При необходимости, сможете установить и добавить в задачу по аналогией с другими плагинами.

Устанавливаем gulp-file-include и пишем задачу для html:

Здесь вы увидели немного новую конструкцию. В src аргумент стал массивом, в котором один из элементов обозначени восклицательным знаком(!) в начале. Это на языке JavaScript буквально означает «не«. То есть мы берём все файлы html ‘src/**/*.html’ , но только не те, которые ‘ !src/components/**/*.html ‘ находятся в директории src/components. В дальнейшем это позволит нам создавать файлы модулей, которые не должны попасть в build директорию, а служат, так сказать, служебными шаблонами. Об этих шаблонах мы поговорим ниже.

Создадим аналогичную задачу для php. Абсолютно такую же, один в один., кроме исключений. Они нам в этой задаче не потребуются.

Задачи для изображений

Здесь всё будет несколько сложнее. Нам потребуется как минимум две задачи для svg, две для растровых изображений. Что нам нужно:

Сжимать растровые изображения.

Конвертировать растровые изображения в webp.

Объединять svg в спрайт.

Включать svg в виде класа с фоном в CSS и cоздавать для svg класс с псевдоэлементами ::after и ::before

Это всё мы будем делать разными задачами и тут нам понадобится просто тонна разных плагинов! Их так много, что я решил оформить их названия в отдельный список и убрать под спойлер.

Плагины для изображений

gulp-changed — понадобится нам для отслеживания изменения в файле. Если файл не изменился, дальнейшие действия с ним не производятся.

gulp-multi-dest — понадобится нам для складывания результатов обработки в несколько директорий.

imagemin-pngquant — и этот тоже сжимает изображения

gulp-webp — конвертирует растровые форматы (png, jpeg) в webp

gulp-svg-css-pseudo — добавляет svg фоном в css и сразу же создаёт псевдоэлементы

gulp-svg-sprite — склеивает все svg в один спрайт. Лично я им пользуюсь крайне редко, но это ввиду особенностей проектов. Вообще весьма полезен для снижения запросов к серверу.

Теперь создадим под всё это файлы задач: tasks/rastr.js , tasks/webp.js , tasks/svg_css.js и tasks/svg_sprite.js . Самая сложная задача будет для растровых изображений, ввиду того, что там много настроек, для объяснения значаний которых нужна отдельная статья. Здесь я детали всех настроек описывать не буду. Just belive me, что я долго сидел подбирал эти настройки с дизайнером так, чтобы качество графики сильно снижало трафик и не сильно резало глаз. В итоге у нас получился вот такой монстр:

В этой задаче мы применили фильтр по расширениям файлов таким образом, чтобы обрабатывались только конкретные расширения: src(‘src/img/**/*.+(png|jpg|jpeg|gif|svg|ico)’) . В данном случае прямой слеш (знак | ) означает буквально «или». Таким образом, при обработке эта функция выберет файлы с данными расширениями, а все остальные просто проигнорирует. Так же с помощью gulp-changed мы запретим обработку старых изображений — это ускорит выполнение задачи. Для того же, чтобы выполнение задачи не вызывало ошибку, если входящих файлов для конвертации нет — используем gulp-plumber.

Теперь создадим webp-дубликаты этих изображений. Эти дубликаты мы будем делать одновременно и в директорию src, и в build, банально для того, чтобы path-intellisense подсказывал нам пути к ним.

Следующий этап — обработка SVG. Здесь у нас будет две задачи: добавление svg в качестве отдельного класса фоном прямо в css и создание svg-спрайта. У этих задач, хоть и похожее, но всё-же разное назначение. Я сейчас не буду вдаваться в подробности, поскольку они не предмет данной статьи. Если вам интересно, зачем нужны svg-спрайты и как этим пользоваться, то об этом писали тут и тут. Давайте перейдём к установке нужных плагинов и написанию задач.

Прежде всего, нам нужно очистить наш svg от всего лишнего. Для этого я буду использовать gulp-svgmin.

Для добавления svg в качестве background-image я буду использовать плагин gulp-svg-css-pseudo. Точнее это форк плагина gulp-svg-css, который я сделал после того, как авторы оригинального плагина не добавили мой пропоуз в свой плагин. Разница между ними заключается в том, что он создаёт для каждого класса псевдоэлементы ::before и ::after. Вы можете точно так же использовать оригинальный плагин, но он не будет работать с псевдоэлементами. На входе мы в определённую директорию кладём файл, например myicon.svg, а на выходе получаем классы —svg__myicon , —svg__myicon-before и —svg__myicon-after , у которых background-image уже задан в виде нашей картинки. Это очень просто и удобно, если картинку не нужно менять (анимировать или изменять цвет):

И так, мы будем брать файлы из директории src/svg/css и обрабатывать нашими плагинами, получая на выходе файл svg.scss и положим его в директорию src/scss/base. Полный файл этой задачи будет выглядеть так:

Теперь напишем задачу для svg-спрайта. Смысл спрайта в том, что он объединяет svg в один файл, который содержит набор векторных картинок. К этим картинкам можно обращаться по ID и вставлять их в нужное место с возможностью изменять их (например цвет) средствами css. Установим плагин gulp-svg-sprite и создадим под него вот такую задачу:

На выходе мы получим файл src/img/sprite.svg внутри которого и будут все наши svg. Обратиться к ним в html можно будет так: <img src=»sprite.svg#myIconFileName»> или так:

Если же иконка находилась во вложенной директории (например, как в нашем случае, в директории css), то перед именем файла нужно поставить имя этой директории и два дефиса. Вот так: <img src=»sprite.svg#css—myIconFileName»>

Чуть позже покажу ещё и третий способ вставлять svg в html с помощью сборки. Вы можете использовать любой из этих способов или их комбинировать, в зависимости от задач, которые нужно решить.

Задачи для шрифтов

Здесь у нас будет две задачи. Первая направлена на конвертацию шрифтов из формата ttf в форматы woff и woff2. Во всех остальных форматах в 2021 году не вижу никакого смысла, поскольку поддержка формата woff простирается аж до Internet Explorer 9. Давно ли вы видели компьютеры с IE9 на борту? Конвертиролвать будем с помощью двух плагинов: gulp-ttftowoff2 и gulp-ttf2woff, соответственно. Файл задачи для конвертации шрифтов будет выглядеть так:

После того, как шрифты сконвертированы, нам нужно их подключить. Я так и не смог добиться полной автоматизации подключения шрифтов, объединения их по жирности и стилю начертания, в зависимости от имени файла и присвоения нескольких вариантов локального имени. Тем не менее, процесс подключения тоже можно немного автоматизировать. Для этого, во-первых, создадим в директороии src/scss/base файл _mixins.scss . В дальнейшем, он нам ещё понадобится и для других миксинов. Напишем в этом файле следующий миксин:

В этот миксин нам нужно будет передать такие параметры:

$name — имя шрифтового семейства;

$file — имя файла;

$weight — жирность шрифта (по-умолчанию установлено значение 400, но если мы передадим параметр, то значение по-умолчанию будет проигнорировано)

$style — стиль начертания (тоже установлен по-умолчанию normal)

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

Далее нам нужно написать задачу, которая будет подключать наши шрифты. По сути эта задача будет циклом проходиться по файлам, брать имя каждого файла, отсекать расширение и на основе имени генерировать код для его подключения через миксин. Для этого нам потребуется модуль nodeJS для работы с файлами, который называется fs. Он уже установлен вместе с nodejs, поэтому устанавливать его нет необходимости — нужно только подключить: const fs = require(‘fs’);

Далее создадим две переменные. В первую запишем, путь к файлу, который получим на выходе, а во вторую — путь к директории шрифтов, которые нам создала предыдущая задача.

Дальнейший код этой функции я честно скопировал у Максима Васяновича ( @MaxGraph ), с его урока про Gulp и немного переписал. В итоге, у нас получится вот такая функция:

Эта функция на выходе создаст нам файл src/scss/_local-fonts.scss , в котором под каждый файл шрифтов будет содержаться вызов миксина для его подключения. Так же, при выполнении функции в консоль будет выдаваться следующее сообщение:

Как видите, в сообщении написано следующее: «Добавлен новый шрифт: названиешрифта. Пожалуйста, переместите вызов миксина из src/scss/_local-fonts.scss в src/scss/_fonts.scss после чего измените его«. Давайте разберёмся, что куда нужно переместить и как изменить. Но прежде создадим тот самый файл src/scss/_fonts.scss — он будет содержать уже реальные вызовы миксина для подключения шрифтов, которыми мы и будем пользоваться.

Когда мы добавляем шрифты, чаще всего, у нас есть отдельные файлы для разной жирности шрифта и для разных стилей начертания (наклонные и прямые, тонкие и жирные и т.п.). Каждый такой файл шрифта создаст отдельный вызов миксина и на выходе мы получим файл src/scss/_local-fonts.scss примерно такого содержания:

Как видим, мы подключаем шрифты отдельными названиями. Это неправильно с точки зрения читабельности и удобства использования шрифта, поскольку вместо того, чтобы прописывать font-weight: 700, нам каждый раз придётся указывать font-family: «ArialBold». Это плохая практика, поэтому нам нужно переписать эти вызовы. Как помним из миксина, который мы написали, первым параметром он принимает имя шрифтового семейства. В данном случае это «Arial». Второй параметр мы не меняем — это имя файла без расширения (расширения подставит миксин). Третий параметр отвечает за жирность. Изменим во второй строке 400 на 700. Четвёртый параметр, который здесь не указан, отвечает за стиль начертания. В третей строке миксин вызывается для наклонного шрифта, поэтому четвёртым параметром нужно это указать. В итоге получим:

Теперь это всё нужно переместить в файл src/scss/_fonts.scss , который, естественно, необходимо предварительно создать. Перемещать нужно в новый файл по той причине, что при следующем запуске эта функция перезапишет файл src/scss/_local-fonts.scss и все наши изменения затрутся.

Автоматическое обновление и синхронизация браузеров

Нам нужно настроить Gulp таким образом, чтобы он при запуске открывал наш проект в браузере и автоматически обновлял его при каких-либо изменениях. Я для этого использую browser-sync. Этот плагин создаёт сервер средствами nodejs и позволяет подключать к нему различные браузеры. Для него у нас будет две задачи — для html-разработки и для php соответственно. Установим этот плагин и создадим два соответствующих файла задач. В первом файле мы укажем настройки для разработки html.

Параметр host отвечает за IP-адрес компьютера, с которого сайт будет раздаваться на другие устройства в сети. Важно, чтобы там был указан именно IP-адрес вашего компьютера в локальной сети, если хотите иметь доступ к разрабатываемому сайту со всех устройств. Коллбэк-функция отвечает за открытие страницы 404, если она есть и если не найдена запрашиваемая (по умолчанию это страница index.html). Все остальные параметры вы вольны настраивать как вашей душе угодно, согласно документации.

Для php мы напишем гораздо более простую задачу. Она будет только обновлять браузер в случае изменений, а локальный сервер Вы будете запускать с помощью сторонней программы: openserver, wamp или любой другой.

Теперь нам нужно подключить в ранее написанные задачи browser-sync и pipe для обновления браузера в конце выполнения задачи. Как подключить — вы уже знаете: так же, как и др угие плагины. А добавлять pipe мы будем следуюший: .pipe(bs.stream()) .

Перезагружать страницу нам придётся при изменении html, scss и js, php, а так же растровых картинок. Соответственно, в эти задачи я уже добавил нужный pipe.

Лично мне нравится, когда в консоли показывается исходный размер изображений до сжатия и итоговый — после сжатия, поэтому в сборку я добавил плагин gulp-size, но поскольку я почти не нашёл единомшленников в данном вопросе «засорения терминала лишней инфой», я не описывал его здесь. При желании вы можете добавить соответствующий pipe к нужным задачам. В публично доступной версии сборки его так же нет.

Далее нам следует заняться функциями вотчинга. Вотчинг — это состояние, когда вся наша программа запущена, следит за файлами и их изменением и выполняет те или иные функции, если эти файлы изменились. И так, за чем будем следить: html, php, scss, js, json (ниже объясню, для чего), изображения в src, изображения в build (помните, что у нас webp конвертируются из уже сжатых изображений?), svg, шрифты. Давайте напишем соответствующую задачу:

Здесь мы использовали два варианта запуска и выполнения задач — parallel и series. Разница между ними в том, что в первом случае задачи запускаются одновременно и выполняются параллельно друг другу, а во втором — последовательно, одна за другой в том порядке, в котором мы указали.

Обратите внимание на имя нашей функции. Поскольку переменная watch уже занята методом галпа, мы назвали свою функцию несколько иначе.

Вот и всё. Мы научили Gulp следить за файлами и выполнять те или иные задачи в тот момент, когда эти файлы изменились.

Деплой на хостинг по FTP

Для этого нам потребуется отдельная задача и плагин. Я использую vinyl-ftp, хотя есть аналоги, без проблем делающие то же самое. Установим его и напишем задачу. На хостинг будем грузить только директорию build/ , в которой находятся готовые, скомпилированные файлы проекта. Для вывода результата в консоль я буду использовать тот же chalk.

Константа connect — это функция, в которую аргументом передаётся объект с настройками хостинга — адрес сервера, логин, пароль. Будьте аккуратны, выкладывая подобные данные на Github или другое хранилище кода. Я создал отдельный файл tasks/ftp_settings.json с настройками и рекомендую вам добавить его в gitignore, чтобы случайно не забыть и не вывалить свои логин и пароль к хостингу на весь мир:

Не забудьте так же указать правильную директорию на ftp-сервере вместо public_html/ , которая указана в моих настройках newer и dest.

Написание GULP- и NPM-сценариев

Теперь нам нужно составить несколько gulp-сценариев, то есть поочерёдного запуска задач для того, чтобы собирать воедино наш проект.

Для этого у нас будет две gulp-задачи: default и php, с той лишь разницей, что мы будем запускать тот или иной сервер, а так же несколько сценариев npm для запуска разработки, запуска сборки проекта и для деплоя на хостинг.

Для начала нам необходимо задать все написанные ранее функции в gulpfile.js, чтобы они были доступны в gulp. Делать мы это будем так же, как мы делали с функцией hello:

После этого создадим сценарии, которые будем выполнять при запуске Gulp с теми или иными параметрами:

Сценарий для html (он же — сценарий по-умолчанию)

Итоговый gulpfile.js будет выглядеть так:

Теперь перейдём в файл package.json и напишем несколько npm-сценариев, которые будут последовательно выполнять задачи и запускать сборку. В объекте «scripts» мы можем задавать в формате ключ-значение имя и наборы задач для запуска. Я сделаю пять сценариев:

html будет запускать Gulp для разработки в html-версии;

php будет запускать Gulp для разработки в php-версии;

build будет поочерёдно запускать задачи для сборки проекта в build без запуска вотчинга и сервера;

ftp отправит содержимое пдиректории build кроме файловых карт (файлы с расширением .map) на ftp-сервер;

build-ftp поочерёдно выполнит build и ftp сценарии.

Создание базовых шаблонов

Для разработки нам потребуются стартовые шаблоны html, кое-какие стили и несколько миксинов, которыми мы будем пользоваться в разработке. Начнём с html. Создадим индексный файл (index.html) со стандартной базовой разметкой:

Теперь уберём в компонент то, что будет повторяться на всех страницах:

. и подключим этот компонент вместо обычного head страницы:

Как можете видеть, ничего сложного нет. Функция @@include принимает два параметра. Первый параметр — путь к файлу, который мы импортируем, а второй — json-объект (тут может быть путь к файлу json, содержащему объект или массив), в котором в формате ключ-значение указаны те переменные, которые нам нужно подставить в этом инклюде. Создадим в директории компонентов так же шаблоны хедера, футера и подключения скриптов:

_header.html

_footer.html

_scripts.html

И теперь подключим их все в индексный файл:

Теперь при запуске Gulp на выходе мы получим готовую страницу, с прописанным head, header, footer и подключенными скриптами. Если после запуска gulp посмотреть на индексный файл в директории build, то мы увидим вполне обычный html-файл:

build/index.html

build/index.html

Теперь перейдём к созданию базовых стилей. Для начала, я подключу все необходимые директории с файлами в style.scss. Здесь важен порядок импорта стилей, поскольку стили, которые будут ниже в итоговом файле имеют приоритет:

Далее создам в директории src/scss/base файл _01_normalize.scss Именно так: с подчёркиванием и номером файла. Это нужно для того, чтобы стили из этого файла оказались в самом верху и их можно было перебить другими стилями, если это понадобится. Далее в этот файл я скопирую стили из normalize.css. Безусловно, можно подключить normalize в качестве плагина, но я выбрал именно этот способ, в том числе, для демонстрации принципов подключения файлов со стилями.

Теперь перейдём к файлу src/scss/base/_mixins.scss. Добавим сюда несколько миксинов, чтобы было удобно задавать быстрые стили:

Этот миксин поможет нам с фоновыми картинками. Достаточно нужному классу написать @include bg и на выходе мы получим вот это:

Следующий миксин, который я использую — это анимация кнопок (при наведении, фокусе и нажатии):

Далее идёт миксин для сброса стилей кнопки. Очень часто такой необходим.

Следующий миксин достаточно спорный, но я исплоьзую. Он делает transition:

И ещё один миксин для контейнеров:

Теперь перейдём в файл src/scss/global/_global.scss и создадим несколько «служебных» классов и общих стилей. Я и не припомню проекта, где они не были бы мне нужны.

Во-первых, установим box-sizing: border-box для всех элементов страницы:

Во-вторых, распишем стили для флексов:

В-третьих, для html и body заранее установим некоторые стили:

И далее момент спорный, но я использую. Это сброс отступов у некоторых блочных элементов:

И того, у нас должны получиться файлы:

Вот, собственно и всё. Поздравляю! Наша сборка готова к работе.

Краткое howto

Первое что следует сказать, что с помощью @@include-функции вы можете вставлять не только html файлы, но и любые другие, в которых есть текстовая информация. Например, вы можете вставлять инлайновые svg в html, не загромождая код.

Второе. В функции @@include есть особый режим @@loop, который принимает вторым аргументом массив объектов и повторяет элемент столько раз, сколько объектов есть в массиве. То есть можно создать, например, слайдер с разными картинками, скормив функции @@loop массив путей к картинкам. ВАЖНОЕ ОГРАНИЧЕНИЕ! loop не работает внутри includ’а — только в корневых файлах.

Третье. Старайтесь дробить свой код на как можно большее количество компонентов. Так вам будет удобнее разрабатывать свои проекты. В директории components можно создавать вложенные директории, в которых хранить шаблоны html, scss и js отдельного компонента (например, слайдера). Scss и js из этой директории подтянутся в выходные файлы, можете об этом не переживать.

Вместо послесловия

Если вы дочитали аж до сюда, значит статья была для вас интересной и познавательной. Поэтому, пожалуйста, пройдите по этой ссылке и поставьте звезду моей сборке. Вам это 10 секунд времени, а мне будет приятно и я буду понимать, что есть запрос на дальнейшее развитие сборки.

Если же Вы знаете, как можно улучшить сборку, отрефакторить какую-то задачу, то напишите об этом в комментариях, а лучше, оставьте свой pull-request в репозитории. Я всегда открыт к улучшениям и готов обсуждению.

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *