Отправить только измененённые файлы с помощью Gulp
Введение | |
Решение | |
Gulpfile.js | |
Нерешённые проблемы |
Введение
Если Вы ведёте разработку на локальном копьютере и работаете с .html или .php
файлами или вообще с любыми файлами, которые нужно
редактировать и затем отправлять на хостинг, то Вы наверняка задумывались
об автоматизации этого процесса.
Раз Вы читаете эту статью, значит в качестве инструмента автоматизации Вы выбрали
Gulp
Изучив основы Gulp Вы скорее всего уже умеете копировать папки и файлы из одной директории в другую.
Умеете следить за изменениями
файлов с помощью gulp.watch и даже можете настроить автоматическую отправку файлов на
хостинг
Если Вы что-то из этого пропустили - не беда, изучите мои статьи:
Как скопировать папку с помощью Gulp | |
Объединить и сжать несколько css файлов в один | |
Как отправить файлы по ftp с помощью Gulp | |
Gulp series |
Вооружившись этими знаниями можно попробовать настроить свою рабочую среду. Но вдруг оказывается,
что файлов в проекте могут быть тысячи, а не один как в онлайн курсах.
Копировать их даже из папки
в папку кажется избыточным действием, а уж по ftp так вообще бессмысленным.
Нужно копировать только тот файл который был изменён, а не всё подряд. Поиск решения обычно
приводит к плагину gulp-changed , только этот способ подходит не всем.
Дело в том, что gulp-changed сравнивает между собой две директории SRC и DEST, т.е. Вам всегда нужно
иметь двойное количество файлов, что само по себе не такая уж и проблема - почти всегда есть версия
разработчика и переработанный дистрибутив. Проблемой будет отправка по ftp - нужно следить за папкой
назначением и вычленить оттуда свежезаписанный файл.
В данный момент я считаю, что проще перехватить измененный файл ещё на стадии первого gulp.watch
и работать с ним в потоке с помощью .on('changed')
Решение
В качестве примера будем мониторить папку app и все .php файлы в ней.
Создадим обычный gulp.task watch внутри которого запустим gulp.watch но не простой а с .on('change' ,function(path, stats)
Результат будем отправлять сразу в два gulp.dest - один будет папкой ./dist , в которой мы будем хранить все
обработанные файлы. Второй gulp.dest будет специальной папкой ./preFtp.
Эту папку мы будем мониторить отдельным gulp.watch и всё что туда попадёт будет сразу отправлено на хостинг
с помощью vinyl-ftp.
После отправки на хостинг будем очищать папку с помощью del
Gulpfile.js
В этом примере мы будем пользоваться пакетами vinyl-ftp, del и будем пользоваться series
npm install vinyl-ftp --save-dev
npm install gulp del --save-dev
const gulp = require('gulp'),
{ series } = require('gulp'),
ftp = require( 'vinyl-ftp' ),
del = require('del');
function getConn()
{
console.log("MY_LOG: getConn function is running!");
return ftp.create({
host: 'heihei.ru',
user: 'andreyolegovich',
pass: 'password',
});
}
const globs = [
'./preFtp/**/*.*',
];
function deploy(cb)
{
console.log('MY_LOG: deploy Task is running');
var conn = getConn();
return gulp.src( globs, { base: './preFtp', buffer: false } )
.pipe(conn.dest( '' ) );
cb();
}
exports.deploy = deploy;
function cleanPreFtp(){
console.log('MY_LOG: cleanPreFtp is running')
return del('./preFtp/**/*.*');
}
exports.cleanPreFtp = cleanPreFtp;
function watchPreFtp (cb) {
console.log('MY_LOG: watch saw something in PreFtp folder');
cb();
}
gulp.task('watch', function() {
gulp.watch("./app/**/*.php").on('change', function(path, stats) {
console.log('Changes detected in app/ file "' + path + '", ' + stats);
gulp.src(path, { base: './app', buffer: false })
.pipe(gulp.dest('./dist'))
.pipe(gulp.dest('./preFtp'))
});
gulp.watch("./preFtp/**/*.*", series(watchPreFtp,deploy,cleanPreFtp));
});
Нерешённые проблемы
deploy запускается два раза потому что папка очищается, а это тоже изменение.
В результате на сервер
отправляется ничего - вроде бы не страшно, но лишний коннект ни к чему.
Не до конца понятно как работает function(path, stats) а это краеугольный
камень всего решения.