Gulp - сборщик проектов, написанный на языке программирования Javascript. Предназначен для автоматизации типовых задач, возникающих при работе с проектом (копирование, преобразование, компиляция файлов и многое другое).
В данной статье я рассмотрю настройку gulp
для проекта, состоящего из двух частей - тестовый (app-vue.loc) и продакшн (vue.loc). Создавать/изменять файлы, настраивать сборщик будем на тестовом, а копироваться и собираться все будет на продакшн. В статье все отражено как есть со всеми путями к локальным проектам.
Программное окружение:
- Windows 10;
- OpenServer (Apache 2.4, PHP 7.4, MariaDB 10.1);
- PHPStorm;
- GIT.
Подготовка рабочего пространства
Для установки gulp
и настройки сборщика необходим менеджер пакетов npm
, который идет в составе Node.js
. Поэтому качаем node.js с офф. сайта и устанавливаем его как обычную программу.
Далее, для работы потребуется рабочая среда: Visual Studio, PHPStorm, WebStorm и т.д. Я использую, по большей части, PHPStorm. Качаем то, что по душе и устанавливаем.
Подготовка проекта
Структура проекта
Для начала создадим такую структуру проекта:
-vue-app.loc
--index.html
--main.js
Здесь всего два файла: точка входа index.html
и основной файл со скриптами main.js
, в нем будут подключаться библиотеки с помощью системы сборки.
Настройка сборщика
После того как убедились, что Node.js
установлен и все работает, открываем терминал и вводим следующую команду для инициализации проекта:
npm init
Нам будут заданы вопросы по проекту. Можем заполнить поля либо пропустить, это не принципиально. Можно будет дозаполнить в файле package.json
.
Установка Jquery
Проект инициализирован! Теперь можно приступать к установке библиотек. Установим Jquery
. Вводим в терминал следующую команду:
npm install jquery
В корне проекта будет создана директория node_modules
. Ее не нужно трогать, в нее будут сваливаться все необходимые библиотеки.
Далее открываем файл main.js
и выписываем туда следующую конструкцию:
const $ = require("jquery");
Такая конструкция подключит закачанный нами jquery
в проект с помощью системы сборки, но ее у нас пока нет поэтому работать не будет! Ее настроим чуть позже. Для начала, нужно установить gulp
.
Установка gulp
Запускаем следующую команду:
npm install gulp --save-dev
После этого, в файле package.json
появится запись о gulp
:
Далее создаем в корне проекта файл gulpfile.js
. В этом файле мы определим логику работы сборщика. Пишем следующий код в файл:
const gulp = require("gulp");
gulp.task("copy-html", () => {
return gulp.src("./app/src/index.html")
.pipe(gulp.dest(dist));
});
Внутри блока gulp.task
мы описываем задачу, которая будет выполняться. В данном случае, будет скопирвоан файл index.html из указанного места в другое указанное место. В принципе, можно это по тестировать и по вводить команду gulp copy-html
в терминал попутно меняя содержимое файла index.html
. Таким образом, мы увидим, что команда отрабатывает корректно, в противном случае, искать ошибку!
Установка модулей для gulp
1. Browserify
Модуль, позволяющий использовать конструкции require('modules')
и проводить сборки зависимостей.
Документация - ссылка.
Устанавливаем его через терминал в режиме разработки:
npm install browserify --save-dev
2. Vinyl-source-stream
Обеспечивает наилучшее взаимодействие browserify
с gulp
.
Документация - ссылка.
Устанавливаем в режиме для разработки:
npm install vinyl-source-stream --save-dev
Далее, приводим файл gulpfile.js
к следующему виду:
const gulp = require("gulp");
const source = require('vinyl-source-stream');
const browserify = require('browserify');
const dist = "C:/OpenServer/domains/vue.loc/admin";
//Копирует index.html, с которым мы работаем
gulp.task("copy-html", () => {
return gulp.src("./app/src/index.html")
.pipe(gulp.dest(dist));
});
//Собирает js-файл из main.js. В Последнем же будут прописаны директивы для сборки типа require.
//Конечный файл будет помещен по указанному адресу в константе dist
gulp.task("build-js", () => {
return browserify('./app/src/main.js').bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest(dist))
});
В итоге, мы имеем 2 задачи:
- Копирование
index.html
в директориюadmin
на проде. - Сборка
bundle.js
на основеmain.js
и отправка его в директориюadmin
на проде.
В качестве проверки делаем следующее:
- Приводим
index.html
к следующему виду:<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h1>Hello World</h1> <script src="bundle.js"></script> </body> </html>
- Добавялем в
main.js
простой скрипт для плавного исчезновения заголовкаh1
. Окончательный видmain.js
должен быть таким:const $ = require("jquery"); $('h1').fadeOut('slow');
- Запускаем две команды в терминале:
gulp guild-js gulp copy-html
После этого должен собраться файл bundle.js
и поместиться в директорю C:/OpenServer/domains/vue.loc/admin
вместе с файлом index.html
. Открываем страницу Index.html
в директории admin
и видим как заголовок исчезает.
Но если посомтреть исходный код и сам файл bundle.js
то видно, что он громоздкий и сложно разобраться где какой модуль и где наш код подключен.
Поэтому можно для разработки сделать файлы раздельными, для этого прописываем в файле gulpfile.js
для browserify
такой параметр - {debug: true}
.
return browserify('./app/src/main.js', {debug: true}).bundle()
В итоге, имеем уже такую структуру:
3. Установка babelify
Сам Babel нужен для трансормации js-кода новых стандартов в более старые для поддержки старыми браузерами, а babelify
позволяет взаимодействовать Babel
с gulp
.
Документация Babel - ссылка.
Документация babelify - ссылка.
Установка через терминал для режима разработки:
npm install --save-dev babelify @babel/core @babel/preset-env
babelify установлен. Приводим задачу сборки bundle.js
в файле gulpfile.js
к следующему виду:
//Собирает js-файл из main.js, в котором мы пропишем директивы сбора, переименовывает его и помещает по указанному адресу
gulp.task("build-js", () => {
return browserify('./app/src/main.js', {debug: true})
.transform("babelify", {presets: ["@babel/preset-env"], sourceMaps: true})
.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest(dist))
});
Таким образом, прежде чем собираться, наш файл bundle.js
к старому формату JavaScript для поддержки старыми браузерами.
4. Установка gulp scss. Работаем со стилями.
Компилирует scss в css
Документация - ссылка.
Запускаем в терминале следующую команду установки:
npm install gulp-sass --save-dev
Пакет установлен, далее, создаем директорию scss
в директории src
и добавляем файл style.scss
. Архитектура приложения должна иметь следующий вид:
Добавляем в style.scss
небольшое правило:
h1 {
color: red;
}
Теперь добавим новую задачу для gulp
в файле gukpfile.js
также добавив константу с подключением gulp-sass
в начале файла:
const gulp = require("gulp");
const source = require('vinyl-source-stream');
const browserify = require('browserify');
const sass = require('gulp-sass');
.../*Старый неизменный код*/...
gulp.task("build-sass", () => {
return gulp.src('./app/scss/style.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest(dist));
});
Тестируем запуская поочередно:
gulp build-sass
gulp copy-html
gulp build-js
Все должно собраться и на странице админки должен пропадать уже красный заголовок
Доработка проекта
- Добавляем две директории в директорию
app
-api
иassets
; - Дорабатываем
gulpfile.js
, чтобы он также копировал все файлы из директорий api и assets в проект. Добавляем такие задачи в файл:gulp.task("copy-api", () => { return gulp.src('./app/api/**/*.*') .pipe(gulp.dest(dist + "/api")); }); gulp.task("copy-assets", () => { return gulp.src('./app/assets/**/*.*') .pipe(gulp.dest(dist + "/assets")); });
- Добавляем в директорию
api
файлapi.php
и добавляем простой код для тестирования:<?php echo "Hello world!";
- Запускаем
gulp copy-api
и убеждаемся, что в основной проект в директориюadmin/api
скопировался файлapi.php
.
Автоматизируем gulp
Добавляем в конец файла gulpfile.js
такой таск:
gulp.task("watch", () => {
gulp.watch('./app/src/index.html', gulp.parallel('copy-html'));
});
В двух словах: когда будет изменяться файл index.html
, будет запускаться метод parallel
, который запусти copy-html
и скопирует файл в проект.
Теперь, запускаем gulp watch
и система будет отслеживать изменения в файле index.html
и при сохранении файла копировать его в проект.
Делаем все тоже самое для остальных файлов проекта, добавляем в gulpfile.js
следующие элементы для watch:
gulp.task("watch", () => {
gulp.watch('./app/src/index.html', gulp.parallel('copy-html'));
gulp.watch('./app/api/**/*.*', gulp.parallel('copy-api'));
gulp.watch('./app/assets/**/*.*', gulp.parallel('copy-assets'));
gulp.watch('./app/src/**/*.js', gulp.parallel('build-js'));
gulp.watch('./app/scss/**/*.scss', gulp.parallel('build-sass'));
});
Примечание. Чтобы остановить слежение за файлами достаточно нажать ctrl + C.
Теперь делаем так, чтобы мы могли собрать все файлы одной командой build
, добавляем в gulpfile.js
следующее:
gulp.task("build", gulp.parallel('copy-html', 'copy-api', 'copy-assets', 'build-js', 'build-sass'));
Можно максимально автоматизировать формирование проекта на лету сделав так, чтобы проект билдился и вставал в режим слежки одной командой gulp
. Добавляем в gulpfile.js
следующее:
gulp.task("default", gulp.parallel("watch", "build"));
Теперь просто пишем в терминал gulp
и можем спокойной работать с проектом. Тестируем, вносим изменения в разные файлы, все будет отражаться на реальном проекте.
На этом подготовка проекта и первоначальная настройка сборщика закончена!
Прочие вопросы
1. Как подключить файл css/scss
из установленной библиотеки в node_modules
.
Пока я это делаю так:
gulp.task("build-sass", () => {
return gulp.src(['./src/scss/style.scss', './node_modules/magnific-popup/dist/magnific-popup.css'])
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({browsers: ['last 2 version', '> 2%', 'firefox 15', 'safari 5', 'ie 6', 'ie 7', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4']}))
.pipe(gulp.dest(dist + '/css/'))
});
То есть добавляю в массив src
дополнительный путь к файлу. Он в dist
вывалится отдельным файлом скомпиленым.