Сборка Вootstrap 4 проекта с использованием Gulp

Сборка Вootstrap 4 проекта с использованием Gulp
Содержание:
  1. Инструкция по установке Gulp окружения
  2. Как использовать Gulp окружение?
  3. Описание Gulp окружения
  4. Комментарии

В этой статье рассмотрим пример Gulp окружения, которое можно использовать для комфортной фронтенд разработки веб-проекта. Данный пример по умолчанию сконфигурирован для создания сайтов и веб-приложений, в основу которых положен фреймворк Bootstrap 4.

Проект, рассматриваемый в рамках этой статьи расположен на Github по адресу: https://github.com/itchief/b4-boilerplate

Видео к этой статье:

Инструкция по установке Gulp окружения

Для создания окружения необходимо иметь следующие установленные программы:

  • "Node.js" (загрузить установщик "Node.js" для своей операционной системы можно c этой страницы; для проекта требуется версия программы не ниже 10);
  • "Gulp" (установить Gulp можно посредством выполнения в консоли следующей команды: npm install -g gulp-cli).

Последняя версия этого проекта (v.2.3.0) основана на Gulp 4 версии.

Если вы используете первую версию проекта, то дополнительно необходимо ещё установить пакетный менеджер Bower.

Node.js, Gulp и Bower. Инструменты, посредством которых можно создать окружение для комфортной разработки сайтов на Bootstrap 4

Установка Gulp:

Установка глобальной версии Gulp 4

Ключ -g указывает npm, что пакет необходимо загрузить не в текущую, а в общую папку.

Выполнение инсталляции программы Bower осуществляется аналогично Gulp (актуально только для версии проекта 1.0.0):

npm install -g bower

После установки основных программ необходимо загрузить с Github архив проекта. Для этого можно воспользоваться этой ссылкой. Последняя версия проекта имеет номер 2.2.3.

Далее следует распаковать архив и перенести файлы из каталога "gulp-project-bootstrap-4" в корневую директорию проекта.

Если нужна не текущая, а какая-то определённая версия (например, 1.0.0), то её можно загрузить со страницы Releases.

Следующий этап – это установка npm пакетов и их зависимостей. Для этого в консоли (должны находиться в корневой директории проекта) необходимо выполнить команду:

npm install

Данная команда установит все пакеты, которые нужны как для работы самого окружения, так и для фронтенда. Выполняет npm эти действия в соответствии с инструкциями, написанными в файле "package.json".

При использовании первой версии проекта (1.0.0), в которой используется менеджер пакетов Bower, необходимо выполнить ещё команду:

bower install

Данная программа установит фронтенд пакеты, указанные в файле "bower.json".

Как использовать Gulp окружение?

Открыть командную строку (путь должен указывать на корневую папку проекта) и ввести gulp (обычный режим):

gulp

После ввода этой команды запустится задача по умолчанию, т.е. "default". Эта задача в свою очередь запустит серию других задач: "build", "webserver" и "watch".

Задача "build" выполнит сборку проекта для продакшена (т.е. она запустит "clean:build", "html:build", "css:build", "js:build", "fonts:build" и "image:build"). Эти задачи поместят в папку "assets/build" результирующие файлы проекта.

Задача "webserver" предназначена для запуска локального веб-сервера с «живой перезагрузкой» страниц в браузере. С помощью него можно очень просто посмотреть проект и выполнить его тестирование.

Задача "watch" используется для отслеживания изменения исходных файлов в папке "assets/src" и выполнение если это призошло различных задач. Другими словами, она позволяет автоматически запускать необходимые задачи и поддерживать результирующие файлы (содержимое папки "assets/build") в актуальном состоянии.

Запуск gulp:

Запуск gulp

Кроме этого можно выполнять выборочную (самостоятельную) сборку той или иной части проекта.

Например, для сборки только CSS части сайта достаточно ввести команду:

gulp css:build

Список других задач:

gulp clean:build // для очистки каталога "assets/build"
gulp html:build // для сборки HTML файлов
gulp js:build // для сборки JS файлов
gulp fonts:build // для сборки шрифтов
gulp image:build // для сборки изображения

Описание Gulp окружения

В этом разделе разберём:

  • основные инструменты и файловую структуру Gulp окружения;
  • как осуществляется подключение исходников Bootstrap к проекту и их настройка;
  • как самостоятельно (с нуля) выполнить инициализацию Gulp проекта и установку зависимостей (без использования готового package.json)
  • как с нуля выполнить инициализацию Bower и установку фронтенд пакетов (без использования готового "bower.json")*;
  • содержимое файла сборщика проекта Gulp (gulpfile.js)

* Менеджер пакетов Bower не используется в проекте, начиная с версии 2.0.0.

Список инструментов

Окружение, предназначенное для разработки фронтенд проекта (сайта), построено на базе следующих инструментов:

  • Node.js (среды, в которой будет выполняться окружение);
  • npm (пакетного менеджера, входящего в Node.js; будет использоваться для загрузки Gulp, плагинов и фронтенд пакетов);
  • jQuery, Popover, Bootstrap (пакеты, которые будут использоваться для сборки css и js частей сайта);
  • Gulp и его плагины (будут использоваться для сборки проекта и выполнения других веб задач).

В первых версиях проекта дополнительно ещё использовался пакетный менеджер Bower. Он применялся за загрузки библиотек jQuery, Popover и Bootstrap. В версиях проекта, начиная с 2.0.0, загрузка данных библиотек выполняется посредством npm.

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

Файловую структуру проекта можно организовать по-разному. Это может зависеть как от предпочтений конкретного разработчика, так и от проекта, для которого она создаётся.

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

Файловая структура проекта на Bootstrap 4, сборка которого выполняется с помощью Gulp

В корне проекта расположена папка "assets" и файлы "gulpfile.js", "package.json". Файл "gulpfile.js" будет содержать задачи для сборщика проекта Gulp.

В первой версии проекта также использовались файлы ".bowerrc" и "bower.json". Файл "bower.json" - это конфигурационный файл менеджера Bower, на основании которого определялись необходимые для загрузки фронтенд пакеты. В данном проекте он использовался для загрузки Bootstrap, jQuery и Popper.

В папке "assets" находятся две папки: "src" (для исходных файлов) и "build" (для готовых файлов; в эту папку их будет помещать сборщик Gulp). В папке "src" расположены каталоги "fonts" (для шрифтов), "img" (для исходных изображений), "js" (для js-файлов), "style" (для стилей) и "template" (для HTML фрагментов) и файл "index.html".

В первой версии проекта в папке "src" ещё находилась директория "bower_components". Она предназначалась для компонентов, загрузка которых выполнялась с помощью Bower. В текущей версии её нет.

В каталоге "js" распологаются два файла: "main.js" и "my.js". Файл "my.js" используется для написания своих скриптов, а "main.js" – для определения списка файлов, содержимое которых необходимо будет включить в итоговый js-файл. Под итоговым понимается файл, который должен получиться на выходе (в каталоге "build").

Директория "style" отведена под стили. В данной директории находятся три файла: "main.scss" (содержит список файлов, содержимое которых необходимо включить в итоговый файл стилей), "my.scss" (используется для написания своих стилей) и "variables.scss" (содержит SCSS переменные, с помощью которых будем изменять стили Bootstrap 4, а также использовать его для создания своих переменных).

Файл "index.html" - это главная страница создаваемого проекта. Кроме "index.html" в данную директорию можно поместить и другие html страницы.

Директория "template" предназначена для помещения в неё фрагментов HTML страниц. Например, в данной директории можно создать файлы "head.html" и "footer.html", и импортировать их содержимое (используя синтаксис //= путь_к_файлу) сразу в несколько страниц. Это позволит более просто создавать и редактировать html страницы, т.к. отдельные части страниц уже будут находиться в отдельных файлах.

Подключение исходников Bootstrap 4 к проекту и их настройка

Как работать с исходниками Bootstrap 4

Существуют разные способы подключения фреймворка Bootstrap 4 к проекту, а также варианты работы с ним.

Наиболее гибкий вариант заключается в использовании исходных кодов. В этом случае можно не только очень просто изменять дефолтные стили Bootstrap, но и подключать к проекту только те классы и компоненты, которые в нём будут использоваться.

Исходные коды CSS стилей Bootstrap 4 написаны на языке SCSS и представлены посредством большого количества небольших файлов.

Список SCSS файлов (расположены в каталоге "node_modules/bootstrap/scss/"): "functions.scss", "variables.scss", "mixins.scss", "variables.scss", "print.scss", "reboot.scss", "type.scss", "images.scss", "code.scss", "grid.scss", "tables.scss", "forms.scss", "buttons.scss", "transitions.scss", "dropdown.scss" и др.

Каждой такой файл выполняет либо определённую служебную задачу, либо отвечает за стилизацию какой-то определённой функции фреймворка или компонента. Файлы SCSS имеют краткие и понятные имена. Используя только их можно достаточно точно понять назначение каждого из них.

Настройка или изменение дефолтных стилей Bootstrap 4 осуществляется посредством переопределения значений переменных SCSS. Все SCSS переменные для удобства собраны в одном месте (в файле "variables.scss"). Но, переопределять их значения желательно, конечно же, не в этом файле, а в своём (например, имеющим такое же имя "variables.scss", но находящемся в "assets/style/variables.scss").

Например, изменение цвета тем success и danger, осуществляется посредством изменения значений переменных $green и $red:

// Переопределение дефолтных значений переменных Bootstrap 4
$red:   #cc2eaa;
$green: #2ecc71;

Обратите внимание, что после копирования переменных Bootstrap 4 в свой файл CSS ("assets/style/variables.scss"), у них необходимо убрать метку !default.

Метка !default предназначена для установления SCSS переменной значения по умолчанию. Если же у SCSS переменной уже есть значение, то новое значение, если оно указано с ключом !default, установлено не будет.

Указать какие исходные SCSS файлы Bootstrap 4 должны участвовать при компиляции в CSS, а какие нет, выполняется посредством SCSS файла "assets/style/main.scss". Другими словами именно содержимое этого файла и будем определять тот набор стилей, который после компиляции будет подключен к веб-странице.

Кроме этого, к этому файлу также подключёны файлы "assets/style/variables.scss" (для переопределения переменных Bootstrap) и "assets/style/my.scss" (для создания своих стилей).

Содержимое файла "main.scss" (пример):

// Переопределение дефолтных значений переменных Bootstrap 4 и определение своих
@import "variables";

// Подключение нужных SCSS исходников Bootstrap 4
@import "../../../node_modules/bootstrap/scss/_functions";
@import "../../../node_modules/bootstrap/scss/_variables";
@import "../../../node_modules/bootstrap/scss/_mixins";
@import "../../../node_modules/bootstrap/scss/_root";
@import "../../../node_modules/bootstrap/scss/_reboot";
@import "../../../node_modules/bootstrap/scss/_type";
@import "../../../node_modules/bootstrap/scss/_images";
@import "../../../node_modules/bootstrap/scss/_code";
@import "../../../node_modules/bootstrap/scss/_grid";
@import "../../../node_modules/bootstrap/scss/_tables";
@import "../../../node_modules/bootstrap/scss/_forms";
@import "../../../node_modules/bootstrap/scss/_buttons";
@import "../../../node_modules/bootstrap/scss/_transitions";
@import "../../../node_modules/bootstrap/scss/_dropdown";
@import "../../../node_modules/bootstrap/scss/_button-group";
@import "../../../node_modules/bootstrap/scss/_input-group";
@import "../../../node_modules/bootstrap/scss/_custom-forms";
@import "../../../node_modules/bootstrap/scss/_nav";
@import "../../../node_modules/bootstrap/scss/_navbar";
@import "../../../node_modules/bootstrap/scss/_card";
@import "../../../node_modules/bootstrap/scss/_breadcrumb";
@import "../../../node_modules/bootstrap/scss/_pagination";
@import "../../../node_modules/bootstrap/scss/_badge";
@import "../../../node_modules/bootstrap/scss/_jumbotron";
@import "../../../node_modules/bootstrap/scss/_alert";
@import "../../../node_modules/bootstrap/scss/_progress";
@import "../../../node_modules/bootstrap/scss/_media";
@import "../../../node_modules/bootstrap/scss/_list-group";
@import "../../../node_modules/bootstrap/scss/_close";
@import "../../../node_modules/bootstrap/scss/_toasts";
@import "../../../node_modules/bootstrap/scss/_modal";
@import "../../../node_modules/bootstrap/scss/_tooltip";
@import "../../../node_modules/bootstrap/scss/_popover";
@import "../../../node_modules/bootstrap/scss/_carousel";
@import "../../../node_modules/bootstrap/scss/_spinners";
@import "../../../node_modules/bootstrap/scss/_utilities";
@import "../../../node_modules/bootstrap/scss/_print";

// Подключение своих SCSS файлов
@import "my";

Кроме этого, для работы некоторых компонентов Bootstrap 4 нужен ещё JavaScript код.

Список js-файлов Bootstrap 4 (находятся в каталоге "node_modules/bootstrap/js/dist/"): "util.js", "alert.js", "button.js", "carousel.js", "collapse.js", "dropdown.js", "modal.js", "tooltip.js", "popover.js", "scrollspy.js", "tab.js" и "toast.js".

Определение какие js-файлы фреймворка Bootstrap 4 необходимо включить в итоговый js-файл проекта, а какие нет, выполняется посредством "main.js".

Импортирование нужных файлов в результирующий build/main.js осуществляется посредством следующей конструкции:

//=  путь_к_файлу

Выполняет это действие будет Gulp плагин "gulp-rigger". Как его установить и подключить будет описано ниже.

В данный файл можно также импортировать jQuery, Popper (необходим для работы компонентов Dropdown, Tooltip и Popover) и при необходимости свои js-файлы.

Содержимое файла "main.js" (пример):

// Импортируем jQuery
//= ../../../node_modules/jquery/dist/jquery.js

// Импортируем Popper
//= ../../../node_modules/popper.js/dist/umd/popper.js

// Импортируем необходимые js-файлы Bootstrap 4
//= ../../../node_modules/bootstrap/js/dist/util.js
//= ../../../node_modules/bootstrap/js/dist/alert.js
//= ../../../node_modules/bootstrap/js/dist/button.js
//= ../../../node_modules/bootstrap/js/dist/carousel.js
//= ../../../node_modules/bootstrap/js/dist/collapse.js
//= ../../../node_modules/bootstrap/js/dist/dropdown.js
//= ../../../node_modules/bootstrap/js/dist/modal.js
//= ../../../node_modules/bootstrap/js/dist/tooltip.js
//= ../../../node_modules/bootstrap/js/dist/popover.js
//= ../../../node_modules/bootstrap/js/dist/scrollspy.js
//= ../../../node_modules/bootstrap/js/dist/tab.js
//= ../../../node_modules/bootstrap/js/dist/toast.js

// Импортируем другие js-файлы
//= my.js

Как с нуля выполнить инициализацию Gulp проекта и установку зависимостей?

Начинается разработка проекта обычно с создания файла "package.json" (манифеста).

Файл "package.json" будет содержать общую информацию о проекте (название, версию, описание, имя автора и др.), а также данные о пакетах, от которых этот проект зависит.

Для создания манифеста, необходимо перейти в корневую папку проекта и ввести команду:

npm init

Инициализация проекта:

Инициализация проекта

После ввода команды необходимо ответить на следующие вопросы:

  • имя проекта (name) – "bootstrap-4";
  • номер версии (version) – "2.0.0";
  • описание (description) – "Start project with use Bootstrap 4";
  • автор (author) – "itchief.ru";
  • git репозиторий (git repository) - "";
  • точка входа (entry point), тестовая команда (test command), лицензия (license), ключевые слова (keywords) – значения по умолчанию.

На вопрос «Is this ok?» ответим "yes" или нажмём Enter.

В результате в корневой папке проекта появится файл "package.json".

Теперь установим пакеты, которые будем использовать в проекте с помощью следующей команды:

npm install название_пакета --save-dev // установка пакета, при этом информация о нём, автоматически прописывается в секцию "devDependencies" файла "package.json"
npm install название_пакета --save-prod // установка пакета, при этом информация о нём, автоматически прописывается в секцию "dependencies" файла "package.json"

Ключ "--save-dev" или "--save-prod" определяет в какую секцию файла "package.json" попадёт информация о нём.

Список пакетов, которые будут использоваться в проекте:

npm install gulp --save-dev // установка gulp
npm install browser-sync --save-dev // установка browser-sync
npm install gulp-autoprefixer --save-dev // установка gulp-autoprefixer
npm install gulp-cache --save-dev // установка gulp-cache
npm install gulp-clean-css --save-dev // установка gulp-clean-css
npm install gulp-rimraf --save-dev // установка gulp-clean-css
npm install gulp-imagemin --save-dev // установка gulp-imagemin
npm install gulp-plumber --save-dev // установка gulp-plumber
npm install gulp-rigger --save-dev // установка gulp-rigger
npm install gulp-sass --save-dev // установка gulp-sass
npm install gulp-sourcemaps --save-dev // установка gulp-sourcemaps
npm install gulp-uglify --save-dev // установка gulp-uglify
npm install imagemin-jpeg-recompress --save-dev // установка imagemin-jpeg-recompress
npm install imagemin-pngquant --save-dev // установка imagemin-pngquant
npm install gulp-rename --save-dev // установка imagemin-pngquant

npm install jquery --save-prod
npm install popper.js --save-prod
npm install bootstrap --save-prod

После установки всех зависимостей, файл package.json будет иметь следующее содержимое:

{
  "name": "bootstrap-4",
  "version": "2.0.0",
  "description": "Start project with use Bootstrap 4",
  "author": "itchief.ru",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "git://github.com/itchief/gulp-project-bootstrap-4.git"
  },
  "dependencies": {
    "jquery": "^3.4.1",
    "popper.js": "^1.14.7",
    "bootstrap": "^4.3.1"
  },
  "devDependencies": {
    "browser-sync": "^2.26.7",
    "gulp": "^4.0.2",
    "gulp-autoprefixer": "^6.1.0",
    "gulp-cache": "^1.1.2",
    "gulp-clean-css": "^4.2.0",
    "gulp-rimraf": "^0.2.2",
    "gulp-imagemin": "^6.0.0",
    "gulp-plumber": "^1.2.1",
    "gulp-rigger": "^0.5.8",
    "gulp-sass": "^4.0.2",
    "gulp-sourcemaps": "^2.6.5",
    "gulp-uglify": "^3.0.2",
    "imagemin-jpeg-recompress": "^6.0.0",
    "imagemin-pngquant": "^8.0.0",
    "gulp-rename": "^1.4.0"
  }
}

Как с нуля выполнить инициализацию Bower и установку фронтенд пакетов?

Определим папку, в которую Bower будет загружать пакеты. Для этого создадим файл .bowerrc и введём в него следующее:

{
  "directory" : "assets/src/bower_components/"
}

Сохраним файл .bowerrc. Теперь все компоненты будут загружаться в каталог bower_components, находящийся в assets/src/.

Выполним инициализацию Bower (создадим файл-манифест bower.json). Создание файла bower.json можно осуществить с помощью команды (в корневой папке проекта):

bower init
Инициализация Bower

После этого необходимо ответить на следующие вопросы:

  • имя проекта (name) – bootstrap-4;
  • описание (description) – Start project on Bootstrap 4 - itchief.ru;
  • автор (author) – itchief.ru;
  • установить установленные компоненты как зависимости (set currently installed components as dependencies) – Y (Да);
  • хотите вы отметить этот пакет как приватный, это предотвратит его случайную публикацию в реестре Bower (would you like to mark this package as private which prevents it from being accidentally published to the registry) – Y (Да);
  • на остальные вопросы оставим ответы, предлагаемые программой по умолчанию;

В результате этих действий будет создан файл bower.json.

Загрузим Bootstrap 4 и пакеты от которых он зависит (Popper и jQuery) в наш проект с помощью Bower.

Для этого в консоли необходимо ввести следующую команду:

bower install bootstrap#v4.0.0-beta --save

Ключ -save необходим для того, чтобы информацию о пакете записать в секцию dependencies файла bower.json.

В результате bower.json будет иметь следующее содержимое:

{
  "name": "bootstrap-4",
  "description": "Start project on Bootstrap 4 - itchief.ru",
  "authors": [
    "itchief.ru"
  ],
  "license": "ISC",
  "keywords": [],
  "homepage": "",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "assets/src/bower_components/",
    "test",
    "tests"
  ],
  "dependencies": {
    "jquery": "^3.2.1",
    "bootstrap": "^v4.0.0-beta"
  }
}

Если вы не хотите инициализировать Bower (bower.json) с помощью команды bower init и устанавливать пакеты вручную, то можете просто создать файл bower.json (например, с помощью файлового менеджера) и вставить в него вышепредставленное текстовое содержимое. Для установки зависимостей в проект достаточно будет ввести следующую команду:

bower install

Описание файла сборщика проекта Gulp (gulpfile.js)

Все действия, выполненные до этого, были подготовительными. Весь функционал, который будет выполнять создаваемое окружение, будет определяться файлом "gulpfile.js".

Файл "gulpfile.js" представляет собой список задач.

Основные задачи которые будут выполнять этот файл:

  • сбор нескольких файлов стилей в один, компиляция полученного SCSS в CSS, добавление автопрефиксов, минимизация CSS и создание source map;
  • импорт всех необходимых js-файлов в один, минимизация этого файла и создание source map;
  • сбор html файла, перенос шрифтов, обработка (сжатие) картинок и автоматическое обновление страниц посредством Browser Sync.

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

Код файла "gulpfile.js" (при использовании Gulp 4):

'use strict';

/* пути к исходным файлам (src), к готовым файлам (build), а также к тем, за изменениями которых нужно наблюдать (watch) */
var path = {
    build: {
        html: 'assets/build/',
        js: 'assets/build/js/',
        css: 'assets/build/css/',
        img: 'assets/build/img/',
        fonts: 'assets/build/fonts/'
    },
    src: {
        html: 'assets/src/*.html',
        js: 'assets/src/js/main.js',
        style: 'assets/src/style/main.scss',
        img: 'assets/src/img/**/*.*',
        fonts: 'assets/src/fonts/**/*.*'
    },
    watch: {
        html: 'assets/src/**/*.html',
        js: 'assets/src/js/**/*.js',
        css: 'assets/src/style/**/*.scss',
        img: 'assets/src/img/**/*.*',
        fonts: 'assets/srs/fonts/**/*.*'
    },
    clean: './assets/build/*'
};

/* настройки сервера */
var config = {
    server: {
        baseDir: './assets/build'
    },
    notify: false
};

/* подключаем gulp и плагины */
var gulp = require('gulp'),  // подключаем Gulp
    webserver = require('browser-sync'), // сервер для работы и автоматического обновления страниц
    plumber = require('gulp-plumber'), // модуль для отслеживания ошибок
    rigger = require('gulp-rigger'), // модуль для импорта содержимого одного файла в другой
    sourcemaps = require('gulp-sourcemaps'), // модуль для генерации карты исходных файлов
    sass = require('gulp-sass'), // модуль для компиляции SASS (SCSS) в CSS
    autoprefixer = require('gulp-autoprefixer'), // модуль для автоматической установки автопрефиксов
    cleanCSS = require('gulp-clean-css'), // плагин для минимизации CSS
    uglify = require('gulp-uglify'), // модуль для минимизации JavaScript
    cache = require('gulp-cache'), // модуль для кэширования
    imagemin = require('gulp-imagemin'), // плагин для сжатия PNG, JPEG, GIF и SVG изображений
    jpegrecompress = require('imagemin-jpeg-recompress'), // плагин для сжатия jpeg
    pngquant = require('imagemin-pngquant'), // плагин для сжатия png
    rimraf = require('gulp-rimraf'), // плагин для удаления файлов и каталогов
    rename = require('gulp-rename');

/* задачи */

// запуск сервера
gulp.task('webserver', function () {
    webserver(config);
});

// сбор html
gulp.task('html:build', function () {
    return gulp.src(path.src.html) // выбор всех html файлов по указанному пути
        .pipe(plumber()) // отслеживание ошибок
        .pipe(rigger()) // импорт вложений
        .pipe(gulp.dest(path.build.html)) // выкладывание готовых файлов
        .pipe(webserver.reload({ stream: true })); // перезагрузка сервера
});

// сбор стилей
gulp.task('css:build', function () {
    return gulp.src(path.src.style) // получим main.scss
        .pipe(plumber()) // для отслеживания ошибок
        .pipe(sourcemaps.init()) // инициализируем sourcemap
        .pipe(sass()) // scss -> css
        .pipe(autoprefixer()) // добавим префиксы
        .pipe(gulp.dest(path.build.css))
        .pipe(rename({ suffix: '.min' }))
        .pipe(cleanCSS()) // минимизируем CSS
        .pipe(sourcemaps.write('./')) // записываем sourcemap
        .pipe(gulp.dest(path.build.css)) // выгружаем в build
        .pipe(webserver.reload({ stream: true })); // перезагрузим сервер
});

// сбор js
gulp.task('js:build', function () {
    return gulp.src(path.src.js) // получим файл main.js
        .pipe(plumber()) // для отслеживания ошибок
        .pipe(rigger()) // импортируем все указанные файлы в main.js
        .pipe(gulp.dest(path.build.js))
        .pipe(rename({ suffix: '.min' }))
        .pipe(sourcemaps.init()) //инициализируем sourcemap
        .pipe(uglify()) // минимизируем js
        .pipe(sourcemaps.write('./')) //  записываем sourcemap
        .pipe(gulp.dest(path.build.js)) // положим готовый файл
        .pipe(webserver.reload({ stream: true })); // перезагрузим сервер
});

// перенос шрифтов
gulp.task('fonts:build', function () {
    return gulp.src(path.src.fonts)
        .pipe(gulp.dest(path.build.fonts));
});

// обработка картинок
gulp.task('image:build', function () {
    return gulp.src(path.src.img) // путь с исходниками картинок
        .pipe(cache(imagemin([ // сжатие изображений
            imagemin.gifsicle({ interlaced: true }),
            jpegrecompress({
                progressive: true,
                max: 90,
                min: 80
            }),
            pngquant(),
            imagemin.svgo({ plugins: [{ removeViewBox: false }] })
        ])))
        .pipe(gulp.dest(path.build.img)); // выгрузка готовых файлов
});

// удаление каталога build
gulp.task('clean:build', function () {
    return gulp.src(path.clean, { read: false })
        .pipe(rimraf());
});

// очистка кэша
gulp.task('cache:clear', function () {
    cache.clearAll();
});

// сборка
gulp.task('build',
    gulp.series('clean:build',
        gulp.parallel(
            'html:build',
            'css:build',
            'js:build',
            'fonts:build',
            'image:build'
        )
    )
);

// запуск задач при изменении файлов
gulp.task('watch', function () {
    gulp.watch(path.watch.html, gulp.series('html:build'));
    gulp.watch(path.watch.css, gulp.series('css:build'));
    gulp.watch(path.watch.js, gulp.series('js:build'));
    gulp.watch(path.watch.img, gulp.series('image:build'));
    gulp.watch(path.watch.fonts, gulp.series('fonts:build'));
});

// задача по умолчанию
gulp.task('default', gulp.series(
    'build',
    gulp.parallel('webserver','watch')
));

Код файла "gulpfile.js" содержит комментарии. С помощью них поясняется что выполняет тот или иной фрагмент инструкций.

Создание задачи в Gulp выполняется очень просто:

// создание gulp задачи (nametask – название задачи)
gulp.task('nametask', function() {
  // действия, которые должна выполнить задача...
});

Задачи в gulp построены очень просто. Их каркас действий в большинстве случаев можно представить так:

  • получить данные из исходных файлов;
  • обработать исходные данные посредством gulp плагинов;
  • сохранить полученный результат (файлы) в каталог "build".

Если используете Gulp 3, то содержимое файла "gulpfile.js" должно быть следующим:

'use strict';

/* параметры для gulp-autoprefixer */
var autoprefixerList = [
  'Chrome >= 45',
  'Firefox ESR',
  'Edge >= 12',
  'Explorer >= 10',
  'iOS >= 9',
  'Safari >= 9',
  'Android >= 4.4',
  'Opera >= 30'
];

/* пути к исходным файлам (src), к готовым файлам (build), а также к тем, за изменениями которых нужно наблюдать (watch) */
var path = {
  build: {
    html: 'assets/build/',
    js: 'assets/build/js/',
    css: 'assets/build/css/',
    img: 'assets/build/img/',
    fonts: 'assets/build/fonts/'
  },
  src: {
    html: 'assets/src/*.html',
    js: 'assets/src/js/main.js',
    style: 'assets/src/style/main.scss',
    img: 'assets/src/img/**/*.*',
    fonts: 'assets/src/fonts/**/*.*'
  },
  watch: {
    html: 'assets/src/**/*.html',
    js: 'assets/src/js/**/*.js',
    css: 'assets/src/style/**/*.scss',
    img: 'assets/src/img/**/*.*',
    fonts: 'assets/srs/fonts/**/*.*'
  },
  clean: './assets/build/*'
};

/* настройки сервера */
var config = {
  server: {
    baseDir: './assets/build'
  },
  notify: false
};

/* подключаем gulp и плагины */
var gulp = require('gulp'),  // подключаем Gulp
  webserver = require('browser-sync'), // сервер для работы и автоматического обновления страниц
  plumber = require('gulp-plumber'), // модуль для отслеживания ошибок
  rigger = require('gulp-rigger'), // модуль для импорта содержимого одного файла в другой
  sourcemaps = require('gulp-sourcemaps'), // модуль для генерации карты исходных файлов
  sass = require('gulp-sass'), // модуль для компиляции SASS (SCSS) в CSS
  autoprefixer = require('gulp-autoprefixer'), // модуль для автоматической установки автопрефиксов
  cleanCSS = require('gulp-clean-css'), // плагин для минимизации CSS
  uglify = require('gulp-uglify'), // модуль для минимизации JavaScript
  cache = require('gulp-cache'), // модуль для кэширования
  imagemin = require('gulp-imagemin'), // плагин для сжатия PNG, JPEG, GIF и SVG изображений
  jpegrecompress = require('imagemin-jpeg-recompress'), // плагин для сжатия jpeg
  pngquant = require('imagemin-pngquant'), // плагин для сжатия png
  rimraf = require('gulp-rimraf'), // плагин для удаления файлов и каталогов
  rename = require('gulp-rename');

/* задачи */

// запуск сервера
gulp.task('webserver', function () {
  webserver(config);
});

// сбор html
gulp.task('html:build', function () {
  return gulp.src(path.src.html) // выбор всех html файлов по указанному пути
    .pipe(plumber()) // отслеживание ошибок
    .pipe(rigger()) // импорт вложений
    .pipe(gulp.dest(path.build.html)) // выкладывание готовых файлов
    .pipe(webserver.reload({ stream: true })); // перезагрузка сервера
});

// сбор стилей
gulp.task('css:build', function () {
  return gulp.src(path.src.style) // получим main.scss
    .pipe(plumber()) // для отслеживания ошибок
    .pipe(sourcemaps.init()) // инициализируем sourcemap
    .pipe(sass()) // scss -> css
    .pipe(autoprefixer({ // добавим префиксы
        browsers: autoprefixerList
    }))
    .pipe(gulp.dest(path.build.css))
    .pipe(rename({ suffix: '.min' }))
    .pipe(cleanCSS()) // минимизируем CSS
    .pipe(sourcemaps.write('./')) // записываем sourcemap
    .pipe(gulp.dest(path.build.css)) // выгружаем в build
    .pipe(webserver.reload({ stream: true })); // перезагрузим сервер
});

// сбор js
gulp.task('js:build', function () {
  return gulp.src(path.src.js) // получим файл main.js
    .pipe(plumber()) // для отслеживания ошибок
    .pipe(rigger()) // импортируем все указанные файлы в main.js
    .pipe(gulp.dest(path.build.js))
    .pipe(rename({ suffix: '.min' }))
    .pipe(sourcemaps.init()) //инициализируем sourcemap
    .pipe(uglify()) // минимизируем js
    .pipe(sourcemaps.write('./')) //  записываем sourcemap
    .pipe(gulp.dest(path.build.js)) // положим готовый файл
    .pipe(webserver.reload({ stream: true })); // перезагрузим сервер
});

// перенос шрифтов
gulp.task('fonts:build', function () {
  return gulp.src(path.src.fonts)
    .pipe(gulp.dest(path.build.fonts));
});

// обработка картинок
gulp.task('image:build', function () {
  return gulp.src(path.src.img) // путь с исходниками картинок
    .pipe(cache(imagemin([ // сжатие изображений
      imagemin.gifsicle({ interlaced: true }),
      jpegrecompress({
        progressive: true,
        max: 90,
        min: 80
      }),
      pngquant(),
      imagemin.svgo({ plugins: [{ removeViewBox: false }] })
    ])))
    .pipe(gulp.dest(path.build.img)); // выгрузка готовых файлов
});

// удаление каталога build
gulp.task('clean:build', function () {
  return gulp.src(path.clean, { read: false })
    .pipe(rimraf());
});

// очистка кэша
gulp.task('cache:clear', function () {
  cache.clearAll();
});

// сборка
gulp.task('build', [
  'clean:build',
  'html:build',
  'css:build',
  'js:build',
  'fonts:build',
  'image:build'
]);

// запуск задач при изменении файлов
gulp.task('watch', function () {
  gulp.watch(path.watch.html, ['html:build']);
  gulp.watch(path.watch.css, ['css:build']);
  gulp.watch(path.watch.js, ['js:build']);
  gulp.watch(path.watch.img, ['image:build']);
  gulp.watch(path.watch.fonts, ['fonts:build']);
});

// задача по умолчанию
gulp.task('default', [
  'build',
  'webserver',
  'watch'
]);

Комментарии: 175

Alex
Alex
И да, Александр — сделайте на сайте кнопку «Наверх» — коментов много, попасть в начало статьи не так просто!
Ссори — привык, что эта кнопка справа, и не заметил вашу кнопку слева!!!
Alex
Alex
Александр, пытаюсь по аналогии с вашим проектом подключить последнюю версию Bootstrap — 5.1.3
Соответственно, обновил и Popper — установил версию @popperjs/core 2.11.0
Все работает, за исключением одной мелочи — при подключении любого JS-файла Bootstrap в консоли браузера возникает ошибка:

Uncaught TypeError: Class extends value undefined is not a constructor or null
    at main.min.js:formatted:5598
    at main.min.js:formatted:5589
    at main.min.js:formatted:5590
Причем ошибка возникает для первого подключаемого файла, для остальных её нет. JS-файлы Bootstrap подключаю следующим образом:

// Импортируем jQuery
//= ../../../node_modules/jquery/dist/jquery.js

// Импортируем Popper
//= ../../../node_modules/@popperjs/core/dist/umd/popper.js

// Импортируем необходимые js-файлы Bootstrap 5
//= ../../../node_modules/bootstrap/js/dist/alert.js
//= ../../../node_modules/bootstrap/js/dist/base-component.js
//= ../../../node_modules/bootstrap/js/dist/button.js
...
И так далее. Подключение Bootstrap происходит после jQuery и Popper.
Никак не могу понять, от чего возникает ошибка? Что я не учитываю?
Заранее благодарен за помощь!
Sanjar
Sanjar
я подключил
// Импортируем Popper
//=include('../../../node_modules/@popperjs/core/dist/umd/popper.js')

// Импортируем Bootstrap 5
//=include('../../../node_modules/bootstrap/dist/js/bootstrap.js')
и работает нормально.

попробуй.
Александр Мальцев
Александр Мальцев
Так просто собрать js-файл Bootstrap 5 не получится. Лучше просто подключить готовый файл, как это сделал Sanjar в этом комментарии.
Можно даже посредством одной строчкой:
// import js-file Popper & Bootstrap 5
//= ../../../node_modules/bootstrap/dist/js/bootstrap.bundle.js
Сборку js-файла Bootstrap из нужных компонентов можно из его исходных кодов.
После распаковки, выполнить «npm install», далее открыть файл «build-plugins.js» и оставить в нём только нужные компоненты, после этого запустить «npm run js». Затем использовать полученный файл вместо «/node_modules/bootstrap/dist/js/bootstrap.bundle.js».
Sanjar
Sanjar
Вот собрал js вроде работает
правда там немного изменение сделал под себя
github.com/sanyokdb/Bootstrap-5-starter
Александр Мальцев
Александр Мальцев
Таким образом собранный js-файл Bootstrap 5 работать будет с ошибками (tooltip, popover и возможно другие компоненты работать не будут):

Тут лучше, как вы писали раньше, просто подключить готовый js-файл Bootstrap. А после того как определитесь с нужным набором компонентов собрать js-файл из исходных кодов с помощью сборщика, который поставляется вместе с исходными кодами Bootstrap.
Иван
Иван
Александр, а можете объяснить почему с Bootstrap 5 стали такие заморочки? Или это неизвестно?

P.S. Попробовал шаманские пляски, описанные в этом комментарии, разобраться не смог

А есть ли смысл в таких сложностях — намного ли 5й бутстрап лучше?
Александр Мальцев
Александр Мальцев
Там используется скрипт для сборки, которые делает много разных вещей. Просто так получить готовый файл Bootstrap 5 склеив определённые файлы уже не получится. Чтобы это реализовать нужно при сборке в своём файле повторять все эти действия. А зачем всё это делать, если код потом может измениться?
Как вариант, можно просто скачать исходные файлы Bootstrap 5 и получить финальные файлы, используя их скрипты сборки. А потом подключить уже полученные финальные файлы к своему проекту.
Иван
Иван
А «их скрипты сборки» там прямо в явном виде в дистрибутиве? Чего то я туплю как это сделать
Александр Мальцев
Александр Мальцев
Для этого нужно скачать исходные файлы Bootstrap, в них содержится всё необходимое. Если нужно могу написать инструкцию как это сделать.
Иван
Иван
Был бы очень признателен за инструкцию. Мне очень неочевидно, как это сделать. Хотя я и не совсем новичок в WEB-технологиях
Александр Мальцев
Александр Мальцев
Напишу в ближайшее время
Иван
Иван
То есть я правильно понимаю, что нужно из main.scss убрать все
// Подключение нужных SCSS исходников Bootstrap 4
@import "../../../node_modules/bootstrap/scss/*

подключить вручную в файлы проекта два файла: «bootstrap.min.css» и «bootstrap.bundle.min.js», полученные так как сказано тут: itchief.ru/bootstrap/build-from-source

Ну и обновлять эти файлы вручную?

А из package.json проекта Gulp-сборки вообще убрать bootstrap?
Александр Мальцев
Александр Мальцев
Тут как вам лучше будет. SCSS можно собирать и с помощью Gulp, как описано в этой статье. В Bootstrap JavaScript там же особенно нечего настраивать, можно только исключить ненужные компоненты, чтобы размер файла был меньше. Так что можно сначала подключить полный «bootstrap.bundle.min.js», а потом, когда всё уже будет готово собрать сборку из нужных компонентов и заменить этот файл.

Другой вариант: можно создать папку bootstrap в своём проекте и поместить туда исходные коды Bootstrap. Затем проделать все как описано здесь: itchief.ru/bootstrap/build-from-source
После этого подключить в своём проекте CSS и JavaScript файлы, которые будут находиться в bootstrap/dist/. Тут тогда нужно будет открыть два текстовых редактора, например, VS Code. В первом осуществлять настройку исходных кодов Bootstrap, в другом свой проект на Gulp файлы Bootstrap в котором будут просто браться из bootstrap/dist/.

Можно и ещё, наверно, всякие способы придумать. Делайте так, как вам удобнее будет.
Sanjar
Sanjar
Здравствуйте.

если в стилях scss сделать ошибку то gulp начинает вылетать. заново приходиться запускать gulp



как можно исправить? вроде ранее работал норм.
Sanjar
Sanjar
и заметил что размер картинок тоже не уменьшает.



Александр Мальцев
Александр Мальцев
Привет! Поправил эти моменты.
fet
fet
Делаю установку GULP выдает ошибку, подскажите что не так? модуль установил imagmin

g1t.ru/video/ConEmu64_oGLEZGvHpd.png
fet
fet
Делал, еще раз все по видео, запускаю команду npm install, начинает устанавливаться, появляется папка node_modules, а когда завершается установка папка node_modules пропадает и не запускается gulp
Александр Мальцев
Александр Мальцев
Привет! Попробовал создать новый проект, всё отлично. Какая ОС? Какая версия gulp, CLI и Local (gulp -v)? Какая версия node.js (node -v)?
fet
fet
Windows 10 Домашняя

$ node --version
v16.13.0

$ npm --version
8.1.0

$ npx --version
8.1.0

$ gulp --version
CLI version: 2.3.0
Local version: Unknown

Вот пытаюсь установить выдает ошибку
fet
fet
модуль npm install mkdirp установил не помогает
fet
fet
Проблема в модуле gulp-imagemin

http://g1t.ru/video/chrome_LYmvX25yQ9.png

http://g1t.ru/video/ConEmu64_26I96VPggC.png

Рекомендуют этот модуль ставить
// Подключаем compress-images для работы с изображениями
const imagecomp = require('compress-images');
fet
fet
Я так понял, что Вам надо обновить сборку, она уже устаревшая. ( а так все удобно было настроено.
Александр Мальцев
Александр Мальцев
Да, переписал сборку с использованием import вместо require. На Github обновил файлы. Теперь необходимо это протестировать.
Dmitry
Dmitry
Здравствуйте!
Извиняюсь, вопрос скорей не по существу и не к вам. Но очень надеюсь на Вашу помощь. Ушел с винды, перешел на ubuntu 20. Сборка работает в целом нормально, иногда не проходят изменения, терминал молчит, ошибок не выводит, время не меняется, но это редко. А вот как сборку подружить с ламп сервером не могу разобраться. Перестает обновляться, причем странно как то. Если что то менять в файле из template то обновление проходит один раз и все кэш. Если в основном файле то можно обновится раз 10, и опять кэш. Если допустим в файле из template поменял что нибудь а страница в браузере не обновилась перехожу в родительский файл меняю что нибудь и обновления проходят. Если можно подскажите пожалуйста на что обратить внимание. Спасибо!
Александр Мальцев
Александр Мальцев
Здравствуйте! По 20.04 версии не подскажу, использую 18.04. Устанавливаю apache, php, mysql самостоятельно, набор LAMP не использую.
Dmitry
Dmitry
а где нибудь можно почитать про отдельную установку и про настройку? не просто так спрашиваю, с этим ламп мозг закипает. месяца 2 уже с ним воюю, все что есть перечитал уже. А так от ubuntu просто в шоке, очень нравится, все летает, в бетке была лучше чем вин 10 из коробки

значит моя проблема в ламп?
Александр Мальцев
Александр Мальцев
LAMP в Ubuntu устанавливается так:
sudo tasksel install lamp-server
Про проблемы не знаю, попробуйте поставить не бету, а финальный релиз 20.04.
fet
fet
Здравствуйте, скачал по новой проект, все установил как у вас описано, все отлично работает, вот только Autoprefixer не работает, подскажите что надо поправить?
Александр Мальцев
Александр Мальцев
Здравствуйте!
А что с Autoprefixer не так?
Если нужны настройки не по умолчанию, а какие-то конкретные, то тогда, их следует выставить, например, в «packege.json»:
{
  ...
  "browserslist": [
    "> 1%",
    "ie 10"
  ]
}
Ion
Ion
Привет!.

У меня тоже не работает префикс. Пробовал задать browserlist в package.json но не помогло.

И еще один вопрос: как добавить видео к проекту, после компиляции (команда gulp) у меня видео удаляется из папки video что я создал.
Александр Мальцев
Александр Мальцев
Привет!
А для каких браузеров не создаются префиксы, может они не входят в список поддержки, которые вы указали в browserslist.
Исходные файлы не должны удаляться. Может они не переносятся в build? В этом случае добавьте код как это сделано для fonts.
Ion
Ion
Префиксы у меня не для одного браузера не добавляются. Проверил в ie, firefox, opera.
Может browserlist нужно отдельно скачать github.com/browserslist/browserslist#browserslist-?

И насчет добавление видео к проекту спасибо огромное — получилось!
Александр Мальцев
Александр Мальцев
Например, мне нужна поддержка IE10 и других браузеров процент использования которых превышает 1%.
Чтобы это выполнить, мне нужно открыть файл «package.json» и добавить в него после devDependencies раздел browserslist:
{
  ...
  "devDependencies": {
    ...  
  },
  "browserslist": [
    "> 1%",
    "ie 10"
  ]
}
Теперь чтобы проверить, я открою файл «my.scss» и добавлю в него, например, следующие стили:
.flex-container {
  display: flex;
  flex-direction: column;
}
После запуска gulp открою файл «main.css» в build и проверю добавил ли gulp-autoprefixer стили с префиксами для браузеров (в данном случае для IE10 и браузеров с долей > 1%):
...
.flex-container {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
}
Как видно они есть, значит gulp-autoprefixer отрабатывает отлично.
Если у вас что-то не работает может быть вы неправильно описали поддержку необходимых браузеров в browserslist.
Ion
Ion
prnt.sc/sajclh — Спасибо указал last 4 versions и заработал prnt.sc/sajfep. Спасибо большое! Удачи вам во всем!
Роман
Роман
Спасибо большое за сборку. Она слегка устарела и требует обновления:
1) gulp-rimraf — этот плагин объявлен устаревшим в пользу del. Впрочем, несмотря на это, после обновления до 1.0.0 он продолжает работать.
2) gulp-imagemin — при попытке обновить до следующей мажорной версии, перестаёт работать сборка. Максимум, до которого можно его обновлять, это 6.2.0.

Всё остальное обновил до последней версии и всё нормально заработало.
Ещё раз большое спасибо. Будет очень круто, если Вы её обновите и поправите.
Александр Мальцев
Александр Мальцев
Пожалуйста! Обновил сборку (gulp-rimraf заменил на del).
А что не так с gulp-imagemin? На Windows 10 устанавливается всё отлично.
Если вы используете WSL (Ubuntu), то перед выполнением команды npm install установите пакет dh-autoreconf:
sudo apt-get install dh-autoreconf
Данный пакет необходим для успешной установки gifsicle входящей в состав gulp-imagemin.
fet
fet
Здравствуйте, перестал работать Autoprefixer, выдает вот такую ошибку, подскажите пжл. что может быть?

monosnap.com/file/mf4OWDgSNyc2e6VpZEllS1rdEZV95v

Как указано npm update я сделал, но ничего не помогает ((
Александр Мальцев
Александр Мальцев
Уберите для autoprefixer аргументы (он по умолчанию имеет оптимальные настройки):
.pipe(autoprefixer()) // добавим префиксы
fet
fet
Здравствуйте
Как php прикрутить к Вашей сборке? Ниже видел, но там к старой версии, а как к новой версии? подскажите пжл.
Александр Мальцев
Александр Мальцев
Здравствуйте! Если вам нужная совместная разработка, то в gulpfile.js для BrowserSync можно указать опцию proxy:
...
/* настройки сервера */
var config = {
    proxy: "mysite.ru",
    notify: false
};
Далее просто запускаете, например, apache сервер. Мне в последнее время очень нравится использовать для этого систему WSL в Windows 10, т.к. она работает очень быстро. После этого gulp.
fet
fet
Спасибо, все отлично работает, но не работает нормально слайдер и меню, то есть нет плавности, меню просто открывается но не выезжает плавно и слайдер меняется картинка но не листается плавно, в чем может быть проблема?
Свой слайдер подключаю все ок работает есть плавность, не пойму что не так, в консоли ошибок нет, уже голова кепит
Захожу на официальный сайт bootstrap беру готовый код со всеми стилями и скриптами подключенным через cdn вставляю туда код карусели и бутстраповской и тоже не листается слайдер просто меняется картинка, может вы сталкивались и меню так же открывается но нет плавности slidetoggle
Александр Мальцев
Александр Мальцев
Пожалуйста! Информация по анимации карусели, а также почему она может не работать приведена в этом комментарии.
Оксана
Оксана
Александр, спасибо большое за статью.
У меня вопрос: как правильно удалить из css неиспользуемые стили? Не хочется весь bootstrap тянуть с собой.
Раньше для этого использовался UnCSS, но он устарел. Можно его чем-то заменить?
Спасибо.
Александр Мальцев
Александр Мальцев
Здравствуйте!
Так это делается простым комментированием подключаемых файлов в main.scss.
Если, например, не нужны Bootstrap компоненты Pagination, Badge, Alert и Progress, то их следует закомментировать:
...
// @import "../../../node_modules/bootstrap/scss/_pagination";
// @import "../../../node_modules/bootstrap/scss/_badge";
@import "../../../node_modules/bootstrap/scss/_jumbotron";
// @import "../../../node_modules/bootstrap/scss/_alert";
// @import "../../../node_modules/bootstrap/scss/_progress";
...
Оксана
Оксана
Я не совсем это имею ввиду. Например, я задействую таблицы, но далеко не все классы из файла _tables мне нужны. Хочется пробежаться по файлу и оставить только те классы, которые используются в моем html-файле.
Александр Мальцев
Александр Мальцев
Исходные стили Bootstrap 4 находятся в SCSS файлах. Чтобы SCSS код превратить в CSS его необходимо компилировать. При этом стили в этих файлах созданы с использованием переменных. Изменяя им значения, мы можем получить ту или иную сборку Bootstrap (CSS-код). Для этого нам и нужен соответствующий набор инструментов, описанный в этой статье.

Если вы хотите использовать какие-то определённые стили из этого фреймворка, то просто скопируйте их в свой CSS файл. Потому что в этом случае определить какие стили вам нужны, а какие нет, можете только вы сами. Нет никакого волшебного инструмента, который 100% точно может определить нужны ли вам какие-то определенные стили нет. Например, если вы добавляете элемент динамически на страницу или какой-то класс к элементу с помощью JavaScript.

Если, вам не нужные какие-то определённые темы (например, danger, success), то они очень просто удаляются с помощью переменных. Для этого вы просто устанавливаете новые значения переменным и получаете на выходе соответствующий CSS код.
При этом не вижу смысла, если вы используете Bootstrap, что-то удалять, чтобы получить экономию в 20Кбайт, чтобы после этого получить не обновляемый на новые версии CSS код. Это экономия будет меньше, чем одна небольшая картинка. Это практически не скажется на скорости загрузки сайта.
Оксана
Оксана
Александр, спасибо за такой развернутый ответ.
Теперь все понятно. Подключила таким же способом Font Awesome — очень удобно. Еще раз спасибо!)
Сергей
Сергей
Доброго здоровья.

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

Боюсь обновлять версии новых пакетов.
ncu предлагает следующее:
popper.js          ^1.14.7  →  ^1.16.1
 bootstrap           ^4.3.1  →   ^4.4.1
 gulp-autoprefixer   ^6.1.0  →   ^7.0.1
 gulp-cache          ^1.1.2  →   ^1.1.3
 gulp-rimraf         ^0.2.2  →   ^1.0.0
 gulp-imagemin       ^6.0.0  →   ^7.1.0
 gulp-rename         ^1.4.0  →   ^2.0.0
Будут ли совместимы новые версии с предыдущими?
Спасибо. Сергей
Сергей
Сергей
Проверил после обновления до указанных выше версий — всё работает!
[====================] 18/18 100%
All dependencies match the latest package versions :)
Т.е. по состоянию на 14 февраля 2020 года все обновления совместимы с вашей удачной сборкой GULP.

Обновлённые версии пакетов по состоянию на 14.02.2020
popper.js           →   ^1.16.1
bootstrap           →   ^4.4.1
gulp-cache          →   ^1.1.3
gulp-rimraf         →   ^1.0.0
gulp-imagemin       →   ^7.1.0
gulp-rename         →   ^2.0.0
gulp-autoprefixer   →   ^7.0.1
До этого имел большие проблемы с обновлением Gulp 3 до версии Gulp 4. Теперь боюсь любых обновлений.
Сергей
Сергей
После обновления gulp-imagemin с 6.0.0 версии на v.7.1.0 обнаружил проблему в работе.
Разбираться не стал, вернул значение в файле package.json на «gulp-imagemin»: "^6.0.0",
Вновь всё заработало.
Возможно эта проблема только в моей сборке, но будьте осторожны при обновлении пакета:
gulp-imagemin ^6.0.0 → ^7.1.0
Сергей
Сергей
Зато с остальным нет проблем.
Очень понравилась понятная иерархия сборки — всё разложено по полочкам, трудно запутаться, не оставляет возможности думать: «Где, что лежит»?
Александр Мальцев
Александр Мальцев
Спасибо за отзыв. В большинстве случаев обновление пакетов до новых версий проходит гладко. Но, конечно, бывают исключения. Поэтому после обновления нужно, конечно, проверять, чтобы ничто не сломалось.
Sanjar
Sanjar
Здравствуйте. Подскажите как правильно подключить библиотеку. Многие в сети пишут что бовер уже умер. Подскажите пжл как правильно подключат фонтан авесома и силк слайдер. И правильно ли бовер умер?
Sanjar
Sanjar
И можно ли удалять папку node_modules после завершения проекта? А то папка весить много
Александр Мальцев
Александр Мальцев
Здравствуйте.
Просто сейчас Bower уже не такой популярный как раньше, все пакеты есть в npm. В этом окружение используется только npm.
Процесс установки slick карусели и подключения её к проекту осуществляется так:
1. Установка пакета slick-carousel с помощью npm:
npm install slick-carousel
2. Включение стилей карусели в файл «main.scss»:
@import "../../../node_modules/slick-carousel/slick/slick.scss";
3. Включение скрипта карусели в файл «main.js»:
//= ../../../node_modules/slick-carousel/slick/slick.js
Установка и подключение Font Awesome и других пакетов осуществляется аналогично. Т.е. устанавливаете пакет с помощью npm, затем подключаете стили (если они есть) в «main.scss» и скрипты (если они есть) в «main.js».
Александр Мальцев
Александр Мальцев
Конечно, она нужна только для разработки.
Artodox
Artodox
Добрый день Александр, не мгли бы помочь разобраться в чем проблема, всю голову сломал: при добавлении картинки в проект появляется ошибка:

[16:12:48] Using gulpfile /mnt/k/WEB-Dev/G4/gulpfile.js
[16:12:48] Starting 'default'…
[16:12:48] Starting 'build'…
[16:12:48] Starting 'clean:build'…
[16:12:48] Finished 'clean:build' after 54 ms
[16:12:48] Starting 'html:build'…
[16:12:48] Starting 'css:build'…
[16:12:48] Starting 'js:build'…
[16:12:48] Starting 'fonts:build'…
[16:12:48] Starting 'image:build'…
[16:12:54] Finished 'js:build' after 5.92 s
[16:12:54] Finished 'css:build' after 6.21 s
[16:12:54] 'image:build' errored after 6.24 s
[16:12:54] Error in plugin «gulp-cache»
Message:
spawn /mnt/k/WEB-Dev/G4/node_modules/jpeg-recompress-bin/vendor/jpeg-recompress ENOENT
Details:
errno: ENOENT
code: ENOENT
syscall: spawn /mnt/k/WEB-Dev/G4/node_modules/jpeg-recompress-bin/vendor/jpeg-recompress
path: /mnt/k/WEB-Dev/G4/node_modules/jpeg-recompress-bin/vendor/jpeg-recompress
spawnargs: --quiet,--min,80,--max,90,--strip,/tmp/23d8c896-de73-4f24-acf0-9d987990e7cc,/tmp/a1baadb0-f348-4b05-aba0-ab6972001dd1
killed: false
stdout:
stderr:
failed: true
signal: null
cmd: /mnt/k/WEB-Dev/G4/node_modules/jpeg-recompress-bin/vendor/jpeg-recompress --quiet --min 80 --max 90 --strip /tmp/23d8c896-de73-4f24-acf0-9d987990e7cc /tmp/a1baadb0-f348-4b05-aba0-ab6972001dd1
timedOut: false
fileName: /mnt/k/WEB-Dev/G4/assets/src/img/intro1.jpg
domainEmitter: [object Object]
domainThrown: false

[16:12:54] 'build' errored after 6.31 s
[16:12:54] 'default' errored after 6.31 s
[16:12:54] The following tasks did not complete: html:build, fonts:build
[16:12:54] Did you forget to signal async completion?

заранее благодарен.
Александр Мальцев
Александр Мальцев
Привет! Не сталкивался с таким. Попробуй переустановить или обновить пакет. Ошибка происходит только для одной определённой картинки или для всех?
fet
fet
Все установил как у вас описано, все отлично работает, но при смене стилей в my.scss и сохранение страницы не обновляется браузер, а при сохранении в index.html браузер обновляется и изменения происходят, подскажите что может быть не так? где поправить? ошибки никакой не выдает ((
fet
fet
Все разобрался, путь поменялся на css/main.min.css ((( а у меня стоял css/main.css
fet
fet
Здравствуйте, все установил, как в описании.
Но появляется вот такая ошибка:
itchief.ru/assets/uploadify/6/0/4/60476d607fa9fd4ce465bd361eacaf32s.jpg
Подскажите, что я сделал не так и где можно поправить?
Александр Мальцев
Александр Мальцев
В статье была ссылка на предыдущую версию проекта. Изменил ссылку, теперь она ведёт на новый архив. В этой версии код обновлен для корректной работы пакета gulp-autoprefixer.
Подключение owl.carousel можно осуществить так.
1. В main.scss вставить:
@import "../../../node_modules/owl.carousel/dist/assets/owl.carousel";
2. В main.js добавить следующее:
//= ../../../node_modules/owl.carousel/dist/owl.carousel.js
fet
fet
по поводу @import я подключал стили с расширением .css, а надо без него в sass файлах, убрал расширения и все подгрузилось
Александр Мальцев
Александр Мальцев
Молодец, что разобрался. Расширение .css указывать конечно не нужно было.
Artodox
Artodox
Добрый день Александр,
спасибо за сборку! Самая ясная и стабильная из всех, что пробовал. Я занимаюсь графическим дизайном и версткой, но в программировании не силен. Проблема в том, что никак не могу подключить свой «woff2» шрифт к сборке, не подскажете процедуру. Заранее благодарен.
Александр Мальцев
Александр Мальцев
Привет! Спасибо за отзыв.
Для этого нужно в папку «src/fonts» поместить нужные шрифты. Например, поместим в неё «Roboto-Regular.woff2».
После этого этот шрифт нужно подключить.
Для этого в файл «my.scss» нужно, например, добавить следующее:
@font-face {
  font-family: "Roboto";
  src: url("../fonts/Roboto-Regular.woff2") format("woff2");
  font-style: normal;
  font-weight: normal;
}
После этого его можно использовать, например:
h1 {
  font-family: Roboto, sans-serif;
}
Artodox
Artodox
Спасибо, все работает, я немного перемудрил :)
Еще один вопрос: у меня почему то в build main.css(142kb) меньше, чем main.min.css(169kb)
Дмитрий
Дмитрий
Здравствуйте, Александр! Спасибо за данную статью все отлично запускается и работает, особенно хочу отметить эффективное сжатие изображений) У меня такой вопрос: bower на своем сайте сам же рекомендует вместо bower использовать yarn, мне немного не понятно yarn устанавливается отдельно на windows и уже потом с помощью yarn-команд устанавливается gulp или же есть какой-то способ внедрить yarn в gulp?
Александр Мальцев
Александр Мальцев
Привет! Спасибо за добрые слова.
Сейчас в проекте bower не используется, все пакеты устанавливаются через npm.
Если хотите переделать через yarn, то его конечно нужно сначала установить. Но перед установкой yarn нужно установить Node.js, т.к. он от него зависит. После этого установите yarn.
Установка gulp глобально:
yarn global add gulp
Установка пакетов:
yarn install
Дмитрий
Дмитрий
Теперь стало более ясно, спасибо большое!))
AlexD
AlexD
Александр, я специально зарегистрировался, чтобы выразить вам огромную благодарность за материал. Я два дня потратил на поиски ответов и столкнулся с тем, что люди просто не понимают, о чем пишут. Но на вашем сайте я нашел то, что мне очень помогло и очень нужно. Еще раз спасибо!
Александр Мальцев
Александр Мальцев
Я рад что понравилось. Спасибо за отзыв.
Татьяна
Татьяна
Хочу сказать спасибо, отличная работа, все запустилось с первой попытки. И высказать пожелание скорейшего выхода дальнейших Ваших статей и конкретно примера о котором Вы писали выше. Еще раз спасибо за Вашу работу.
Александр Мальцев
Александр Мальцев
Спасибо за отзыв.
Stan
Stan
Александр, приветствую!

Отличная работа и мануал, почёт и уважение. Стал пользоваться вашим решением, до этого пользовался примерным решением и менял от версии к версии. Grunt тоже был в ходу :)

Из моих примечаний, что лучше не «пришивать» jquery и popper, а копировать в проект при разработке. Продакшн версию конечно же лучше сшить.
Хотя палка о двух концах. Здесь ломали копья в споре лучше CDN или своё.

Ну и дополнение

Добавим путь

/* пути к исходным файлам (src), к готовым файлам (build), а также к тем, за изменениями которых нужно наблюдать (watch) */
var path = {
    build: {
        html: 'assets/build/',
        .......
        .......
        copy: 'assets/build/js/vendor/'
    },
Указываем исходники

var sourceFiles = ['node_modules/jquery/dist/jquery.js','node_modules/popper.js/dist/umd/popper.js'];
Подключим (предварительно указав в package.json «gulp-copy»: "^4.0.1")

var copy  = require('gulp-copy'); // плагин для копирования файлов
Добавим задачу

// копирование js
gulp.task('copy:build', function () {
    return gulp.src(sourceFiles)
        .pipe(gulp.dest(path.build.copy));
});
И добавим в сборку

// сборка
gulp.task('build',
    gulp.series('clean:build',
        gulp.parallel(
            ......
            'copy:build',
            ......
        )
    )
);
И не забудем в подключении скриптов указать верный путь: js/vendor/

По аналогии можно копировать что угодно и куда угодно.
Александр Мальцев
Александр Мальцев
Привет!
Благодарю за отзыв и за подробный рецепт, многим пригодится.
А так, да, использовать CDN или нет, это конечно же личные предпочтения и решать каждому.
Denis
Denis
Добрый день!
Все сделал по инструкции но, что, то пошло не так.

[14:52:47] Finished 'copy:build' after 412 ms

  Replace Autoprefixer browsers option to Browserslist config.
  Use browserslist key in package.json or .browserslistrc file.

  Using browsers option cause some error. Browserslist config
  can be used for Babel, Autoprefixer, postcss-normalize and other tools.

  If you really need to use option, rename it to overrideBrowserslist.

  Learn more at:
  https://github.com/browserslist/browserslist#readme
  https://twitter.com/browserslist
Помогите устранить ошибку.
Denis
Denis
Проблема решена!
В доках pipe заменить browsers: ['last 2 versions'] на overrideBrowserslist: ['last 2 versions'] и тогда предупреждение пропадает))
.pipe(autoprefixer({
            overrideBrowserslist:  ['last 2 versions'],
            cascade: false
        }))
fet
fet
Спасибо помогло
Иван
Иван
Здравствуйте! Спасибо за полезную статью. Хочу один момент уточнить, когда импортируем файлы бутстрап, там ведь не обязательно прописывать спереди исходника нижнее подчеркивание.
// подключение нужных SCSS исходников Bootstrap 4
@import "../../../node_modules/bootstrap/scss/_functions";
.......................
Я имею ввиду здесь: _functions. Можно просто
@import "../../../node_modules/bootstrap/scss/functions";
Мы ведь только импортируем эти фалы. На сколько я понял из документации, файлы с нижним подчеркиванием в начале, не компилируются… Но в данном случае мы их не компилируем, а импортируем в файл, который и будет в последствии скомпилирован. Верно ли я понял, что не обязательно тут писать "_"?
Ведь даже в основном файле bootstrap.scss импортируют без этих подчеркиваний.
Александр Мальцев
Александр Мальцев
Да, когда вы указываете компилятору какую-то папку, то он в ней переводит все SCSS файлы в CSS за исключением тех, которые начинаются с нижнего подчёркивания. Эти файлы, начинающиеся с нижнего подчеркивания, игнорируются. Эта принятая в этом языке условность. Т.е. если файл начинается с нижнего подчёркивания, то он является фрагментом и его нужно игнорировать. Он используется в каком-то другом файле.

В этом окружении мы указываем компилятору конкретный файл «assets/src/style/main.scss», в который всё импортировано. Если мы бы указали ему папку, то нужно было бы тогда следить за файлами. Т.е. те, которые нам не нужно включать в build и они являются фрагментом другого файла указывать их с нижнем подчеркиванием. А те файлы, которые должны быть самостоятельными и находиться в результирующей папки (т.е. build/css) указывать без нижнего подчеркивания.

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

А в «gulpfile.js» да, нижнее подчеркивание можно опустить, не указывать.
Иван
Иван
Добрый день! Подскажите ещё, я правильно понял, что файлы бутстрап будут каждый раз пересобираться при изменении нашего файла scss? Грамотно ли будет для бутстрап отдельный таск просто создать? Ведь по идее его только один раз скомпилировать нужно. Или я не прав?
Александр Мальцев
Александр Мальцев
Привет! Да, файлы будут каждый раз пересобираться. Это конечно правильно, только если не нужно брать его по дефолту. Т.к. в большинстве случаев нужно настраивать Bootstrap (устанавливать SASS переменным другие значения). После этого чтобы эти изменения увидеть, его нужно пересобрать. Вот такой процесс.
Что хотите сократить? Если нужен Bootstrap по дефолту, то просто подключите его отдельно, например, через CDN.
Иван
Иван
Добрый день
Если необходимо, что бы были вложенные папки для html — что нужно прописать в gulpfile.js

тесть необходимо, чтобы вложенные HTML в папки также переносились в билд с такой же структурой

prntscr.com/o8yepw
Александр Мальцев
Александр Мальцев
Привет!
Для этого нужно создать папку pages в папке src. Перенести существующий файл «index.html» в эту папку, т.е. в pages.
Открыть этот файл и поменять пути к шаблонам «head.html» и «footer.html»:
...
//= ../template/head.html
...
//= ../template/footer.html
...
После этого открыть файл «gulpfile.js» и поменять в нём путь к исходным html:
var path = {
    ...
    src: {
        html: 'assets/src/pages/**/*.html',
    ...
Добавил в проект на Github новую ветку with-nested-structure.
Natalia
Natalia
Здравствуйте, Александр.
Спасибо за статью.
Пытаюсь установить и запустить проект. Дошла до запуска команды gulp. Появляется сообщение:
$ gulp
[23:15:14] Using gulpfile ~\Documents\WebProjects\test\gulpfile.js
C:\Program Files\nodejs\node_modules\gulp\bin\gulp.js:129
gulpInst.start.apply(gulpInst, toRun);
^

TypeError: Cannot read property 'apply' of undefined
at C:\Program Files\nodejs\node_modules\gulp\bin\gulp.js:129:20
at process._tickCallback (internal/process/next_tick.js:61:11)
at Function.Module.runMain (internal/modules/cjs/loader.js:745:11)
at startup (internal/bootstrap/node.js:282:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)

Вроде бы делаю всё по инструкции. На что посмотреть и что поправить, чтобы gulp запустился как положено?
Александр Мальцев
Александр Мальцев
Здравствуйте.
Проверьте какая у вас версия gulp и nodejs.
Версию Gulp можно узнать так:
npm info gulp version
Должна быть не ниже 4.0.0.
Версию node.js можно проверить так:
nodejs -v
Необходимо иметь 10.x.x.
Natalia
Natalia
С этим всё в порядке.
Gulp — 4.0.2.
Nodejs — 10.14.2.
Александр Мальцев
Александр Мальцев
Значит необходимо проверить установлен ли Gulp в папку с проектом. Для этого перейдите в командной строке в директорию проекта и введите команду:
gulp --version
Если установлена только CLI версия, то запустите на установку gulp в ваш проект:
npm install gulp --save-dev
Если это не поможет, то попробуйте выполнить следующие команды:
npm uninstall -g gulp
npm uninstall -g gulp-cli

npm install -g gulp-cli
npm install gulp --save-dev
Последнюю команду нужно запускать в командной строке, только после того как вы перешли в директорию своего проекта, т.е. из места в котором у вас расположен файл «gulpfile.js».
Natalia
Natalia
Сделала как предложено. Не помогло.
Та же ошибка выдается.
Александр Мальцев
Александр Мальцев
А вы берете с GitHub или сами все создаёте по описанию, представленному на этой странице?
Natalia
Natalia
Пробовала оба варианта — один и тот же результат.
Александр
Александр
Александр, а как сюда прикрутить babel для es6?
Александр Мальцев
Александр Мальцев
Добавил в проект на Github новую ветку with babel.
В этой версии немного изменил логику. Теперь в папке "/src/js" два файла: «vendor.js» и «main.js». В «vendor.js» включаются сторонние библиотеки, а в «main.js» включаются свои js файлы.
Логика работы в этой ветки по сбору js файла такая: сначала собирается файл «main.js» из файлов, который затем обрабатывается с помощью babel; после этого собираются сторонние библиотеки из указанных файлов в «vendor.js»; оба этих собранных файла помещаются в папку "/build/js/cache/"; в конце оба этих файла объединяются в итоговый файл «all.js».

В качестве browserslist установлен defaults. Что обеспечивает поддержку следующих браузеров: > 0.5%, last 2 versions, Firefox ESR, not dead.
Александр
Александр
Добрый день. Отличная сборка. Спасибо. Подскажите, пож-та, а как сделать так чтобы собиралось 2 отдельных файла css. Один условно для главной страницы (main.css), а другой для оформления остальных. При этом 2-й файл также использует bootstrap, sass и минифицируется. Буду очень признателен за ответ.
Александр Мальцев
Александр Мальцев
Добрый!
Для этого создайте дополнительно main2.scss и укажите в нём что должно, например, участвовать в сборке для главной страницы.
Затем создайте дополнительную задачу, которая будет использоваться для подготовки CSS для главной страницы.
// сбор стилей
gulp.task('css2:build', function () {
return gulp.src('assets/src/style/main2.scss') // получим main2.scss

});
После этого добавьте его в другие задачи, где есть css:build:
// сборка
gulp.task('build', [
  'clean:build',
  'html:build',
  'css:build',
  'css2:build',
  ...
Александр
Александр
Спасибо огромное. Вроде бы все получилось. Еще вопрос, по поводу прикрутки php. Да, видел похожий вопрос ниже, но мой немного отличается. Мне необходима работа с php wordpressa, нужно только чтобы отслеживались изменения в файлах php и перезагружался браузер. Т.е. перемещение в папку build не нужно. Ну и файлы php находятся в корне папки с темой, а не в src. Подскажите, плиз, какие изменения внести? Заранее признателен
Александр Мальцев
Александр Мальцев
Отлично!
Добавить задачу:
gulp.task('php:watch', function (done) {
  webserver.reload();
  done();
});
...
// запуск задач при изменении файлов
gulp.task('watch', function () {
  ...
  // установить нужный путь...
  gulp.watch('assets/src/**/*.php', gulp.series('php:watch'));
});
fet
fet
Александр, было бы чудесно, если бы в эту сборку добавили PostCss, очень удобно было бы. Может реализуете?
Александр Мальцев
Александр Мальцев
Пока планов таких нет. Если он вам нужен, можете его добавить самостоятельно.
cleantis
cleantis
Вот такую ошибку при запуске gulp выдает.
C:\Users\admin\Desktop\zp>gulp
internal/modules/cjs/loader.js:584
throw err;
^

Error: Cannot find module 'imagemin-pngquant'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:582:15)
at Function.Module._load (internal/modules/cjs/loader.js:508:25)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at Object.(C:\Users\admin\Desktop\zp\gulpfile.js:62:16)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)

C:\Users\admin\Desktop\zp>
Александр Мальцев
Александр Мальцев
Необходимо учиться читать ошибки. Там же явно написано, что не найден модуль imagemin-pngquant.
cleantis
cleantis
да вроде грамотный, но к сожалению не ставится
C:\Users\admin\Desktop\zp>npm install imagemin-pngquant

> pngquant-bin@5.0.2 postinstall C:\Users\admin\Desktop\zp\node_modules\pngquant
-bin
> node lib/install.js

‼ Command failed: C:\Users\admin\Desktop\zp\node_modules\pngquant-bin\vendor\p
ngquant.exe --version

‼ pngquant pre-build test failed
i compiling from source
? Error: pngquant failed to build, make sure that libpng-dev is installed
at Promise.all.then.arr (C:\Users\admin\Desktop\zp\node_modules\execa\index.
js:231:11)
at process._tickCallback (internal/process/next_tick.js:68:7)
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules\fse
vents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@
1.2.7: wanted {«os»:«darwin»,«arch»:«any»} (current: {«os»:«win32»,«arch»:«x64»}
)

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! pngquant-bin@5.0.2 postinstall: `node lib/install.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the pngquant-bin@5.0.2 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional log
ging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\admin\AppData\Roaming\npm-cache\_logs\2019-03-21T09_43_24_
116Z-debug.log

C:\Users\admin\Desktop\zp>
Александр Мальцев
Александр Мальцев
Он же приводит почему модуль «imagemin-pngquant» не может быть установлен. Это происходит из-за того, что установлен модуль libpng-dev (pngquant failed to build, make sure that libpng-dev is installed).
Вячеслав
Вячеслав
Первая статья, в которой все написано понятно, и ВСЕ РАБОТАЕТ. Вот только не понял, а зачем устанавливать Bootstrap, Jquery и Popper.js дважды — через npm и через Bower?
Александр Мальцев
Александр Мальцев
Нет, Bower сейчас использовать не нужно. Сейчас все пакеты устанавливаются через npm. Он остался в статье для совместимости (для пользователей), которую используют ещё первую версию данной сборки.
Михаил
Михаил
Александр Мальцев, ты лучший. Скачал архив, написал «npm i» и всё работает!
Михаил
Михаил
Только единственное, что не могу понять, у меня не запускается автоперезагрузка сервера при изменениях css и scss файлов, приходится вручную страницу обновлять, хотя если вносить изменения в html то сервер сам перезагружается, Александр, подскажите, в чём может быть дело?
Александр Мальцев
Александр Мальцев
Спасибо за отзыв. Исправил этот недочёт и некоторые другие. В статье обновил ссылку на архив.
Чтобы это исправить можешь либо обновить файлы в своём проекте, либо самостоятельно внести изменения в файл head.html (указать ссылку на минимизированный файл стилей):
<link rel="stylesheet" href="css/main.min.css">
Михаил
Михаил
Изменил ссылку на минимизированный файл стилей, теперь всё обновляется в реальном времени, ты лучший, спасибо.
Dmitry
Dmitry
Возникли проблемы с плагинами для сжатия картинок: «imagemin-pngquant» и «gulp-imagemin»
при установке выдают ошибку:
"… npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm WARN notsup SKIPPING OPTIONAL DEPENDENCY:
Unsupported platform for fsevents@1.2.4:

wanted {«os»:«darwin»,«arch»:«any»}
(current: {«os»:«win32»,«arch»:«ia32»})..."

Видимо, не поддерживают win7. Вы не встречали решения для этой проблемы?
Александр Мальцев
Александр Мальцев
В сообщение выдаётся предупреждение о том, что было пропущено установка необязательной зависимости «fsevents@1.2.4», т.к. она работает только на macOS.

Если есть проблема с плагинами «imagemin-pngquant» и «gulp-imagemin», то попробуйте обновить «Node.js» до последней версии из ветки «10.x.x».

После этого удалите папку с npm пакетами и попробуйте их установить заново с опцией "--no-option", т.е. без установки дополнительных зависимостей:
npm install --no-option
Если это не поможет, то попробуйте поискать другие плагины для обработки картинок (может это связано с архитектурой вашей ОС).
Dmitry
Dmitry
Очень полезная статья, спасибо большое!
KL
KL
Спасибо за подробную инструкцию!
Делаю следующие шаги:
1. git clone github.com/itchief/gulp-project-bootstrap-4.git
2. npm install
3. gulp

Получаю ошибки:
[14:50:28] 'webserver' errored after 158 ms
[14:50:28] Error: listen EPERM :::3000
    at Object._errnoException (util.js:992:11)
    at _exceptionWithHostPort (util.js:1014:20)
    at Server.setupListenHandle [as _listen2] (net.js:1355:14)
    at listenInCluster (net.js:1396:12)
    at Server.listen (net.js:1480:7)
    at module.exports.plugin (/public_html/node_modules/
browser-sync/dist/server/index.js:27:25)
    at Object.startServer [as fn] (/public_html/node_mod
ules/browser-sync/dist/async.js:177:52)
    at /public_html/node_modules/browser-sync/dist/brows
er-sync.js:120:14
    at iterate (/public_html/node_modules/browser-sync/d
ist/utils.js:269:9)
    at /public_html/node_modules/browser-sync/dist/utils
.js:281:21
[14:50:28] 'default' errored after 5.73 s
[14:50:28] The following tasks did not complete: watch
[14:50:28] Did you forget to signal async completion?
Что делаю не так?)
Александр Мальцев
Александр Мальцев
Пожалуйста! Node.js (nodejs -v) и npm (npm -v) какой версии?
Александр Мальцев
Александр Мальцев
Node.js должна быть не ниже 10.x
KL
KL
Обновил до:
node 10.15.0
npm 6.4.1

Сделал всё заново, теперь чуть другие ошибки:

[15:52:07] 'webserver' errored after 207 ms
[15:52:07] Error: listen EPERM: operation not permitted :::3000
    at Server.setupListenHandle [as _listen2] (net.js:1290:14)
    at listenInCluster (net.js:1338:12)
    at Server.listen (net.js:1425:7)
    at module.exports.plugin (/public_html/node_modules/
browser-sync/dist/server/index.js:27:25)
    at Object.startServer [as fn] (/public_html/node_mod
ules/browser-sync/dist/async.js:177:52)
    at /public_html/node_modules/browser-sync/dist/brows
er-sync.js:120:14
    at iterate (/public_html/node_modules/browser-sync/d
ist/utils.js:269:9)
    at /public_html/node_modules/browser-sync/dist/utils
.js:281:21
    at executeTask (/public_html/node_modules/browser-sy
nc/dist/browser-sync.js:136:13)
    at Object.mergeMiddlewares [as fn] (/public_html/nod
e_modules/browser-sync/dist/async.js:166:9)
[15:52:07] 'default' errored after 5.85 s
[15:52:07] The following tasks did not complete: watch
[15:52:07] Did you forget to signal async completion?
Александр Мальцев
Александр Мальцев
Какая ОС? А также версия gulp (gulp -v)?
fet
fet
Александр спасибо, очень приятная сборка, сплошное удовольствие работать, если не затруднит подскажите как все это связать не SASS, а с PostCSS? это надо наверно целую статью переписывать (, может хотя бы примерно укажите направление, что бы понимать куда копать и возможно ли это, bootstrap 4 засунуть в PostCSS? Если бы написали развернуто ) был бы премного благодарен.
Александр Мальцев
Александр Мальцев
Тут, скорее всего, придётся делать двойную связку. Bootstrap 4 написан на SASS, и от этого не куда не деться. Т.е. исходные стили Bootstrap 4 в css компилируете с помощью gulp-sass, а свои в css — с помощью gulp-postcss. После этого полученные промежуточные css файлы объединяете, например, с помощью gulp-concat-css.
Андрей
Андрей
Александр, подскажите, в какой файл нужно добавлять свои брекпойнты? Добавил в свой variables.scss такой массив, но почему-то огни не добавились после компиляции.
$grid-breakpoints: (
    xxs: 0,
    xs: 375px;
    sm: 576px,
    md: 768px,
    lg: 992px,
    xl: 1200px
);

$container-max-widths (
  (
    xs: 375px,
    sm: 540px,
    md: 720px,
    lg: 960px,
    xl: 1140px
  )
);
Александр Мальцев
Александр Мальцев
Новые брекпойнты можно добавлять только в конец списка.
$grid-breakpoints: (
    xs: 0,
    sm: 375px,
    md: 576px,
    lg: 768px,
    xl: 992px,
    vl: 1200px
);
$container-max-widths: (
    sm: 375px,
    md: 540px,
    lg: 720px,
    xl: 960px,
    vl: 1140px
);
Андрей
Андрей
Спасибо, понял)
Nubbie
Nubbie
Здравствуйте, мануал устарел и с актуальным Gulp4 не работает -(
Александр Мальцев
Александр Мальцев
Здравствуйте. Файл gulpfile.js обновлён до Gulp 4. Окружение можно загрузить с github. Статья по настройке окружения будет обновлена в ближайшее время.
Dmitry
Dmitry
Здравствуйте
Как php прикрутить к Вашей сборке? Файл php из папки src ни в какую не хочет перемещаться в папку build, прописывал в файле gulpfile.js php по аналогу html
Спасибо!
У Вас тут столько интересного связанного с php)
Александр Мальцев
Александр Мальцев
Здравствуйте, спасибо!
Для этого достаточно внести следующие изменения в gulpfile.js:
var path = {
  ...
  src: {
    html:  ['assets/src/*.html','assets/src/*.php'],
    ...
  },
  watch: {
    html:  ['assets/src/**/*.html','assets/src/**/*.php'],
    ...
};
Dmitry
Dmitry
Здравствуйте Александр!
Большое спасибо за ответ, помогло, файлы php и .htaccess переносятся из папки src в папку build. Как теперь связать галп с опен сервером для работы с php, не знаю, в интернете много советов но они как то не подходят. если не трудно подскажите пожалуйста.

И еще, хочу попробовать поставить вашу форму обратной связи itchief.ru/bootstrap/feedback-form, папку feedback загрузил в папку src она тоже переносится в папку build, но уже немного легче, может ее как то надо загружать в в папку node modules?

Спасибо!!!
Александр Мальцев
Александр Мальцев
Можно так (на примере домена localhost):
1. Изменить настройки сервера browser-sync:
/* настройки сервера */
var config = {
    /*server: {
        baseDir: './assets/build'
    },*/
    proxy: "localhost",
    notify: false
};
2. В настройках Open Server Panel на вкладке домены для localhost указать в качестве папки домена место, где находится build (например, \localhost\assets\build).

Папку feedback загружайте в src, она не является npm пакетом.
Dmitry
Dmitry
Спасибо!!! с пхп получилось
Dmitry
Dmitry
Здравствуйте
Использую Вашу сборку, такой вопрос, делаю многостраничный сайт. Как сделать так, чтобы скрипты и стили загружались только на той странице сайта на которой используются. Например, под фотогалерею отведена отдельная страница, зачем все скрипты от нее таскать по всему сайту, если они нужны только на одной. Наверное это трудно сделать так? Спасибо!!!
Александр Мальцев
Александр Мальцев
Здравствуйте! Обычно такую задачу решают с помощью RequireJS.
Dmitry
Dmitry
Спасибо! буду пробовать, разбираться)
Denis
Denis
Добрый день!
Я использую Вашу сборку Gulp. Подскажите, что необходимо прописать в gulpfile.js?
Задача: При сборке проекта перенести "папка, с разными файлами разных расширений" из папки "src" со всем её содержимым в папку "build".
Можно без всяких сжатий, как есть 100%.

За ранее спасибо за ответ.
Александр Мальцев
Александр Мальцев
Добрый! Сделайте по аналогии с задачей (task), которая используется для переноса шрифтов.
Denis
Denis
Добрый день!
Подскажите, как правильно добавить в Вашу сборку Gulp -> Vue.js + Vuetify?

За ранее спасибо за ответ.

Egor
Egor
Александр, добрый день!
Подскажите, чем можно заменить команду «gulp.start». Не работает на gulp 4.0.0
Фрагмент кода ниже.
Спасибо.

gulp.task('build:frontend', function () {
  gulp.start(
    'build:frontend:assets:copy-images-vendors',
    'build:frontend:assets:copy-js-vendors',
    'build:frontend:assets:copy-photoswipe-css-and-images',
    'build:frontend:sass:generate-css',
    'build:frontend:sass:generate-module-css'
  )
})
Egor
Egor
Доброго времени суток!
Александр, если возможно, подскажите, как можно заменить команду «gulp.start» в нижеприведенном коде. Проблема в том, что «gulp.start» выпилили в gulp 4.0.0 и скрипт больше не исполняется. Скрипт написан не мной и прекрасно работает на gulp 3.9.1 но не на gulp 4.0.0. К сожалению к разработчику обратиться не могу, так как его «все устраивает».

Спасибо.

/* jslint node: true */
'use strict';

const gulp = require('gulp')
const sass = require('gulp-sass')
const sourcemaps = require('gulp-sourcemaps')
const autoprefixer = require('gulp-autoprefixer')
const rename = require('gulp-rename')
const livereload = require('gulp-livereload')

// backend tasks
gulp.task('build:backend:assets:copy-css-vendors', function () {
  return gulp.src([
    'node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput.css',
    'node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput-typeahead.css',
    'node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.standalone.min.css',
    'node_modules/cropper/dist/cropper.css',
    'node_modules/bootstrap-accessibility-plugin/plugins/css/bootstrap-accessibility.css'
  ])
  .pipe(gulp.dest('./css/vendors'))
})

gulp.task('build:backend:assets:copy-fonts-vendors', function () {
  return gulp.src([
    'node_modules/font-awesome/fonts/**'
  ])
  .pipe(gulp.dest('fonts/vendors'))
})

gulp.task('build:backend:assets:copy-ckeditor', function () {
  var pluginFiles = '/**/*.@(js|png|jpg|jpeg|gif|css|html|svg)'
  return gulp.src(
    [
      'node_modules/ckeditor/adapters/*.js',
      'node_modules/ckeditor/lang/*.js',
      'node_modules/ckeditor/plugins/icons.png',
      'node_modules/ckeditor/plugins/icons_hidpi.png',
      'node_modules/ckeditor/plugins/clipboard' + pluginFiles,
      'node_modules/ckeditor/plugins/codemirror' + pluginFiles,
      'node_modules/ckeditor/plugins/colordialog' + pluginFiles,
      'node_modules/ckeditor/plugins/copyformatting' + pluginFiles,
      'node_modules/ckeditor/plugins/dialog' + pluginFiles,
      'node_modules/ckeditor/plugins/dialogadvtab' + pluginFiles,
      'node_modules/ckeditor/plugins/div' + pluginFiles,
      'node_modules/ckeditor/plugins/docprops' + pluginFiles,
      'node_modules/ckeditor/plugins/iframe' + pluginFiles,
      'node_modules/ckeditor/plugins/iframe' + pluginFiles,
      'node_modules/ckeditor/plugins/image' + pluginFiles,
      'node_modules/ckeditor/plugins/link' + pluginFiles,
      'node_modules/ckeditor/plugins/liststyle' + pluginFiles,
      'node_modules/ckeditor/plugins/pastefromword' + pluginFiles,
      'node_modules/ckeditor/plugins/specialchar' + pluginFiles,
      'node_modules/ckeditor/plugins/table' + pluginFiles,
      'node_modules/ckeditor/plugins/tabletools' + pluginFiles,
      'node_modules/ckeditor/plugins/stylesheetparser' + pluginFiles,
      'node_modules/ckeditor/plugins/templates' + pluginFiles,
      'node_modules/ckeditor/plugins/uicolor' + pluginFiles,
      'node_modules/ckeditor/plugins/widget' + pluginFiles,
      'node_modules/ckeditor/plugins/wsc' + pluginFiles,
      'node_modules/ckeditor/plugins/lineutils' + pluginFiles,
      'node_modules/ckeditor/skins/moono-lisa/**/*.@(css|png|gif)',
      'node_modules/ckeditor/ckeditor.js',
      'node_modules/ckeditor/contents.css',
      'node_modules/ckeditor/styles.js',
      'node_modules/ckeditor/LICENSE.md'
    ],
    {base: 'node_modules/ckeditor'}
  ).pipe(gulp.dest('src/Backend/Core/Js/ckeditor'))
})

gulp.task('build:backend:assets:copy-fine-uploader-css-and-images', function () {
  return gulp.src([
    'node_modules/fine-uploader/jquery.fine-uploader/fine-uploader-new.min.css',
    'node_modules/fine-uploader/jquery.fine-uploader/continue.gif',
    'node_modules/fine-uploader/jquery.fine-uploader/edit.gif',
    'node_modules/fine-uploader/jquery.fine-uploader/loading.gif',
    'node_modules/fine-uploader/jquery.fine-uploader/pause.gif',
    'node_modules/fine-uploader/jquery.fine-uploader/processing.gif',
    'node_modules/fine-uploader/jquery.fine-uploader/retry.gif',
    'node_modules/fine-uploader/jquery.fine-uploader/trash.gif',
    'node_modules/fine-uploader/jquery.fine-uploader/placeholders/waiting-generic.png',
    'node_modules/fine-uploader/jquery.fine-uploader/placeholders/not_available-generic.png'
  ])
  .pipe(gulp.dest('./css/vendors/fine-uploader'))
})

gulp.task('build:backend:assets:copy-js-vendors', function () {
  return gulp.src([
    'node_modules/jquery/dist/jquery.min.js',
    'node_modules/jquery-migrate/dist/jquery-migrate.min.js',
    'node_modules/jquery-ui-dist/jquery-ui.min.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap.min.js',
    'node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js',
    'node_modules/fine-uploader/jquery.fine-uploader/jquery.fine-uploader.min.js',
    'node_modules/simple-ajax-uploader/SimpleAjaxUploader.min.js',
    'node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js',
    'node_modules/cropper/dist/cropper.js',
    'node_modules/bootstrap-accessibility-plugin/plugins/js/bootstrap-accessibility.min.js'
  ])
  .pipe(gulp.dest('js/vendors'))
})

gulp.task('build:backend:sass:generate-css', function () {
  return gulp.src([
    'src/Backend/Core/Layout/Sass/screen.scss',
    'src/Backend/Core/Layout/Sass/debug.scss'
  ])
  .pipe(sourcemaps.init())
  .pipe(sass({
    includePaths: [
      'node_modules/'
    ],
    outputStyle: 'compressed',
    precision: 10
  }))
  .pipe(autoprefixer({}))
  .pipe(sourcemaps.write('./', {
    includeContent: false,
    sourceRoot: 'src/Backend/Core/Layout/Sass'
  }))
  .pipe(gulp.dest('src/Backend/Core/Layout/Css'))
  .pipe(livereload())
})

gulp.task('build:backend', function () {
  gulp.start(
    'build:backend:assets:copy-css-vendors',
    'build:backend:assets:copy-fonts-vendors',
    'build:backend:assets:copy-js-vendors',
    'build:backend:assets:copy-fine-uploader-css-and-images',
    'build:backend:sass:generate-css',
    'build:backend:assets:copy-ckeditor'
  )
})

gulp.task('serve:backend', function () {
  livereload.listen()
  gulp.watch(
    [
      'src/Backend/Core/Layout/Sass/**/*.scss'
    ],
    ['build:backend:sass:generate-css']
  )
})

// frontend tasks
gulp.task('build:frontend:assets:copy-images-vendors', function () {
  var components = {
  }

  for (var key in components) {
    return gulp.src(components[key]).pipe(gulp.dest('./images/vendors/' + key))
  }
})

gulp.task('build:frontend:assets:copy-js-vendors', function () {
  return gulp.src([
    'node_modules/photoswipe/dist/photoswipe.min.js',
    'node_modules/photoswipe/dist/photoswipe-ui-default.min.js',
    'node_modules/slick-carousel/slick/slick.min.js'
  ])
  .pipe(gulp.dest('js/vendors'))
})

gulp.task('build:frontend:assets:copy-photoswipe-css-and-images', function () {
  return gulp.src([
    'node_modules/photoswipe/dist/photoswipe.css',
    'node_modules/photoswipe/dist/default-skin/*.{png,svg,gif,jpg,css}'
  ])
    .pipe(gulp.dest('css/vendors/photoswipe'))
})

gulp.task('build:frontend:sass:generate-css', function () {
  return gulp.src([
    'src/Frontend/Core/Layout/Sass/debug.scss',
    'src/Frontend/Core/Layout/Sass/editor_content.scss',
    'src/Frontend/Core/Layout/Sass/screen.scss'
  ])
  .pipe(sourcemaps.init())
  .pipe(sass({
    includePaths: [
      'node_modules/'
    ],
    outputStyle: 'compressed',
    precision: 10
  }))
  .pipe(autoprefixer({}))
  .pipe(sourcemaps.write('./', {
    includeContent: false,
    sourceRoot: 'src/Frontend/Core/Layout/Sass'
  }))
  .pipe(gulp.dest('src/Frontend/Core/Layout/Css'))
  .pipe(livereload())
})

gulp.task('build:frontend:sass:generate-module-css', function () {
  return gulp.src([
    'src/Frontend/Modules/**/Layout/Sass/*.scss'
  ])
  .pipe(sass({
    includePaths: [
      'node_modules/'
    ],
    outputStyle: 'compressed',
    precision: 10
  }))
  .pipe(autoprefixer({}))
  .pipe(rename(function (path) {
    path.dirname = path.dirname.replace('/Sass', '/Css')
  }))
  .pipe(gulp.dest('src/Frontend/Modules/'))
  .pipe(livereload())
})

gulp.task('build:frontend', function () {
  gulp.start(
    'build:frontend:assets:copy-images-vendors',
    'build:frontend:assets:copy-js-vendors',
    'build:frontend:assets:copy-photoswipe-css-and-images',
    'build:frontend:sass:generate-css',
    'build:frontend:sass:generate-module-css'
  )
})

gulp.task('serve:frontend', function () {
  livereload.listen()
  gulp.watch(
    [
      'src/Frontend/Modules/**/Layout/Sass/*.scss'
    ],
    ['build:frontend:sass:generate-module-css']
  )
  gulp.watch(
    [
      'src/Frontend/Core/Layout/Sass/debug.scss',
      'src/Frontend/Core/Layout/Sass/editor_content.scss',
      'src/Frontend/Core/Layout/Sass/screen.scss'
    ],
    ['build:frontend:sass:generate-css']
  )
})

// Fork-theme tasks
gulp.task('build:theme-fork:sass:generate-css', function () {
  return gulp.src([
    'src/Frontend/Themes/Fork/Core/Layout/Sass/screen.scss'
  ])
  .pipe(sourcemaps.init())
  .pipe(sass({
    includePaths: [
      'node_modules/'
    ],
    outputStyle: 'compressed',
    precision: 10
  }))
  .pipe(autoprefixer({}))
  .pipe(sourcemaps.write('./', {
    includeContent: false,
    sourceRoot: 'src/Frontend/Themes/Fork/Core/Layout/Sass'
  }))
  .pipe(gulp.dest('src/Frontend/Themes/Fork/Core/Layout/Css'))
  .pipe(livereload())
})

gulp.task('build:theme-fork', function () {
  gulp.start(
    'build:theme-fork:sass:generate-css'
  )
})

gulp.task('serve:theme-fork', function () {
  livereload.listen()
  gulp.watch(
    [
      'src/Frontend/Themes/Fork/Core/Layout/Sass/**/*.scss'
    ],
    ['build:theme-fork:sass:generate-css']
  )
})

// public tasks
gulp.task('default', function () {
  gulp.start('build')
})

gulp.task('serve', function () {
  gulp.start(
    'serve:backend',
    'serve:frontend',
    'serve:theme-fork'
  )
})

gulp.task('build', function () {
  gulp.start(
    'build:backend',
    'build:frontend',
    'build:theme-fork'
  )
})

Denis
Denis
Добрый день!
Подскажите, как правильно добавлять плагины в сборке (например: «Owl Carousel 2»)?
Подскажите, как обновлять плагины в файле «package.json» до новой версии?

За ранее спасибо за ответ.
Александр Мальцев
Александр Мальцев
Добрый!
Подключить плагин Owl Carousel 2 можно, например, так:
1. Открыть файл package.json и добавить название пакета owl.carousel в секцию dependencies:
"dependencies": {
  "jquery": "^3.3.1",
  "popper.js": "^1.14.4",
  "bootstrap": "^4.1.3",
  "owl.carousel": "^2.3.4"
}
2. Ввести команду:
npm install
Другой вариант — это просто ввести команду:
npm add owl.carousel
После установки плагина Owl Carousel 2, его необходимо подключить к проекту:
1. Открываем main.js и вставляем в него следующее:
// Импортируем JavaScript Owl Carousel 2
//= ../../../node_modules/owl.carousel/dist/owl.carousel.js
2. Открываем main.scss и вставляем в него следующий код:
// Подключение CSS Owl Carousel 2
@import "../../../node_modules/owl.carousel/dist/assets/owl.carousel.css";
Для обновления пакетов необходимо ввести команду:
npm update
Узнать версию пакета (например, owl.carousel) можно так:
npm view owl.carousel version
Denis
Denis
Супер, большое спасибо за качественный развернутый ответ.
Егор
Егор
Здравствуйте. Я компилирую программой Koala, но вопрос другой: можно ли используя Bootstrap SCSS исключить классы warning, danger и другие, ведь в проекте используется всего 2-3 цвета, плюс цвета типографии? Например нужно оставить default и primary, а остальное связанное с другими классами исключить.
Александр Мальцев
Александр Мальцев
Здравствуйте. Да их можно убрать. Для этого нужно в файле _variables.scss найти строчку со списком тем и оставить только нужные:
$theme-colors: map-merge(
  (
    "primary":    $primary,
    "success":    $success,
    "danger":     $danger
  ),
  $theme-colors
);
В Bootstrap 4 темы default нет, а темы primary, success и danger используется в компонентах. Тема primary используется для стилизации ссылок, progress и др. Темы success и danger в формах. Поэтому их лучше оставить и назначить им необходимые цвета.
Егор
Егор
Спасибо, получилось. success и danger попробовал ради эксперимента убрать, компилятор ошибку выдает и пишет, где еще используются эти переменные.
Denis
Denis
Добрый день!
Подскажите, что можно исправить? При запуске gulp выводит ошибку:
buffer.js:207
    throw new ERR_INVALID_ARG_TYPE(
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type undefined
    at Function.from (buffer.js:207:11)
    at new Buffer (buffer.js:182:17)
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\gulp-rigger\index.js:20:29
    at Rigger.<anonymous> (D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\index.js:719:9)
    at Rigger.emit (events.js:182:13)
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\index.js:252:16
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\node_modules\async\lib\async.js:232:13
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\node_modules\async\lib\async.js:113:21
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\node_modules\async\lib\async.js:24:16
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\node_modules\async\lib\async.js:229:17
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\index.js:391:21
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\index.js:167:7
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\node_modules\async\lib\async.js:232:13
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\node_modules\async\lib\async.js:113:21
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\node_modules\async\lib\async.js:24:16
    at D:\Home_Station\W_M_s\Open_Server\OSPanel\domains\project_220405\node_modules\rigger\node_modules\async\lib\async.js:229:17
Большое спасибо за ответ. Я только начал осваивать gulp.
Александр Мальцев
Александр Мальцев
Тут два варианта. Либо разбираться с исключением, которое выбрасывает buffer.js в связи с тем, что передаётся неправильный тип аргумента. Либо просто создать сначала пустой проект, проверить его работу. Если всё хорошо, то последовательно подключать к файлам main.scss и main.js исходные файлы SCSS и JS.
Denis
Denis
Добрый день!
А можете подсказать как подключить плагин rigger (что прописать в gulpfile), у меня есть рабочий проект с подключенными плагинами, но с rigger не получается. Не подключаются файлы.
Большое спасибо за ответ.
Александр Мальцев
Александр Мальцев
В статье есть информация как это сделать. Попробуйте сделать всё по этой инструкции. На гитхабе есть готовый проект, можете взять его.
Denis
Denis
Добрый день!
Эта ошибка, как раз и возникает при использовании готового проекта с гитхаба. После развертывания командой npm i и запуска команды gulp
Александр Мальцев
Александр Мальцев
Добрый! Там кроме npm, нужно ещё и Bower зависимости установить. Он пытается собрать build из файлов, которых просто нет в каталоге bower_components.

Но Bower является уже устаревшим пакетным менеджером. В новой версии проекта (2.0.0) Bower убран, теперь все зависимости устанавливаются с помощью npm. Также были обновлены версии зависимостей. Так что можете использовать новую версию.

Если нужна старая версия с Bower (1.0.0), то её можно загрузить отсюда.
Denis
Denis
Супер! Огромное спасибо! Все работает.
andrey
andrey
Добрый день.

И что дальше, продолжите урок дальше разверните, чтобы был опыт использования на каком нибудь хотя бы тестовом проекте, чтобы закрепить навыки, а то ни о чем получается…
Александр Мальцев
Александр Мальцев
Добрый! Продолжение будет (на примере создания лендинга).
Alexey
Alexey
Добрый день!
Подскажите, в как установить gulp + modx на реальный удаленный сервер, чтобы при редактировании скриптов и стилей данные автоматически обновлялись на сервере и на экране соответственно. Ну, типа, FTP — тоннель
Спасибо!
Константин
Константин
Помогите решить эту проблему не могу понять почему rigger так себя ведет. Делал все по аналогии.
Не получилось запустить проект, выдает ошибку в консоле:

buffer.js:199
    throw new errors.TypeError(
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type undefined
    at Function.from (buffer.js:199:11)
    at new Buffer (buffer.js:174:17)
    at D:\newProjects\kos.tst\node_modules\gulp-rigger\index.js:20:29
    at Rigger.<anonymous> (D:\newProjects\kos.tst\node_modules\rigger\index.js:719:9)
    at Rigger.emit (events.js:159:13)
    at D:\newProjects\kos.tst\node_modules\rigger\index.js:252:16
    at D:\newProjects\kos.tst\node_modules\rigger\node_modules\async\lib\async.js:232:13
    at D:\newProjects\kos.tst\node_modules\rigger\node_modules\async\lib\async.js:113:21
    at D:\newProjects\kos.tst\node_modules\rigger\node_modules\async\lib\async.js:24:16
    at D:\newProjects\kos.tst\node_modules\rigger\node_modules\async\lib\async.js:229:17
    at D:\newProjects\kos.tst\node_modules\rigger\index.js:391:21
    at D:\newProjects\kos.tst\node_modules\rigger\index.js:167:7
    at D:\newProjects\kos.tst\node_modules\rigger\node_modules\async\lib\async.js:232:13
    at D:\newProjects\kos.tst\node_modules\rigger\node_modules\async\lib\async.js:113:21
    at D:\newProjects\kos.tst\node_modules\rigger\node_modules\async\lib\async.js:24:16
    at D:\newProjects\kos.tst\node_modules\rigger\node_modules\async\lib\async.js:229:17
Александр Мальцев
Александр Мальцев
Тут вам нужно проверять файлы, содержимое которых формируется с помощью rigger (в этой статье такими файлами являются index.html и main.js).

Выполнить это можно, например, посредством исключения файлов. Кроме этого обратите внимание на то, чтобы путь не содержал пробелы и также чтобы их не было в конце конструкции //=.
Алексей
Алексей
Благодарю за статью — даже с опытом написания сайтов в DreamWeaver и немного поработав с пре-процессорами, что-то понял))

Дошел до запуска gulp, и последняя строчка была такой:
[16:24:01] Plumber found unhandled error:
 Error in plugin 'gulp-sass'
И, как совсем новичку в программировании, хотелось бы небольшую статью пример, как весь этот проект использовать — создать простенькую страничку и подгрузить к ней header и footer из каталога templates (очень интересна эта возможность)
Александр Мальцев
Александр Мальцев
Спасибо. Это сообщение «говорит» что у вас ошибка в стилях SСSS.
Хорошо, сделаю статью, в которой опишу, как этот функционал использовать для создания веб-проекта.
Алексей
Алексей
Так вообще ничего пока не делал — просто систему пытаюсь настроить. Стилей пока нет никаких
Александр Мальцев
Александр Мальцев
Тогда проверьте существования файлов, которые вы указали в main.scss.
Евгений
Евгений
Александр, подскажите пожалуйста новичку:
a) зачем нам пакетный менеджер bower (и прицепом git) если у нас уже есть нодовский пакетный менеджер npm? В статье вы при помощи bower ставите bootstrap, но ведь bootstrap можно поставить и через npm? Я так понимаю для гальпа то все равно? Кстати с официального сайта бутстрапа в разделе установка исчезла строчка про bower…
b) огромная куча пакетов, что вы ставите c префиксом gulp- (обработка изображений, сжатия) вы их используете для сборки всего сайта, правильно? Бутсрапа здесь касается только gulp-sass и gulp-autoprefixer судя по официальной документации бутстрапа?
c) Чтобы переопределить стили бутсрапа для своего проекта не обязательно устанавливать «Install Ruby, install Bundler with gem install bundler, and finally run bundle install. This will install all Ruby dependencies, such as Jekyll and plugins.» правильно я понял?
Александр Мальцев
Александр Мальцев
Да, вместо Bower для загрузки Bootstrap 4 можно использовать npm. Bower ушёл в прошлое, поэтому и возможность загрузки Bootstrap 4 с помощью него исчезла. Gulp конечно нет разницы, как вы будете загружать файлы.

Да, такое количество пакетов нужно для сборки всего сайта.
Если вам нужно только CSS, то необходимо установить только те, которые перечислены в таске css:build:
// сбор стилей
gulp.task('css:build', function () {
    gulp.src(path.src.style) // получим main.scss
        .pipe(sourcemaps.init()) // инициализируем sourcemap
        .pipe(sass()) // scss -> css
        .pipe(autoprefixer({ // добавим префиксы
            browsers: autoprefixerList
        }))
        .pipe(cleanCSS()) // минимизируем CSS
        .pipe(sourcemaps.write('./')) // записываем sourcemap
        .pipe(gulp.dest(path.build.css)) // выгружаем в build
});
К gulp-sass и gulp-autoprefixer желательно добавить ещё gulp-clean-css (для минимизации CSS) и gulp-sourcemaps (для создания map файла CSS).

Устанавливать Ruby и Bundler не нужно.
Евгений
Евгений
Спасибо вам большое за вашу статью и за ответ! Открыли новые горизонты для мамонта из каменных 2000-х когда странички верстали таблицами:)
Иван
Иван
Добрый день
Данную процедуру необходимо проводить перед каждым проектом или можно как то уже сделанный проект переносить в новую папку и делать другой сайт?
Александр Мальцев
Александр Мальцев
Добрый день!
Как это выполнять каждый разработчик выбирает сам. Можете просто копировать.

Ну, или делать так:
1. Клонировать репозиторий в новый проект:
git clone https://github.com/itchief/gulp-project-bootstrap-4.git
2. Ввести 2 команды:
npm install
bower install
После выполнения этих 2 действий gulp-проект будет настроен.
ctac
ctac
Статья мега полезная. Пишите еще на такие темы. Еще лучше если бы задания были бы какие-то… А то прочитал, забыл и все…
Александр Мальцев
Александр Мальцев
Спасибо за отзыв.
Константин
Константин
Доброго времени суток, Александр!
Использую в качестве локального сервера OpenServer.
Возникла проблема при установке bower install:

bower EMALFORMED Failed to read c:\openserver\userdata\temp\*******\bower\ca4c50b905dc21ea17a10549a6f5944f-9156-wPQQSX\bower.json

Почему-то он ищет bower.json по этому пути c:\openserver\userdata\temp\*******\bower\ca4c50b905dc21ea17a10549a6f5944f-9156-wPQQSX, а не в папке проета? Там этого файла соответственно нет, хотя сам путь существует. Хотя команду запускаю через консоль из папки проекта.

Сможете подсказать в «какую сторону копать», чтобы решить проблему?
Спасибо.

Александр Мальцев
Александр Мальцев
Здравствуйте, Константин. Может вы находитесь в командной консоли в этой папке. Попробуйте перейти в корневую папку проекта и инициализировать bower в ней.
Teddy_GOD
Teddy_GOD
Это значит что Вы создали файл bower.json до инициализации, удалите его и все заработает
anton
anton
Александр, а это дело без авто обновления, да?
Александр Мальцев
Александр Мальцев
npm пакеты можно обновить так:
npm i -g npm-check-updates
npm-check-updates -u
npm install
Bower пакеты:
bower update