GULP и обновление браузера при изменении в JS
Имеется Gulp сборка, все работает нормально, за исключением одного ньюанса. Иногда при изменении в Js файлах, сборка перестает обновлятся и как будто зависает не сохраняя изменения в Js, в таком случае приходится перезапускать сборку. Помогите пожалуйста с решением.
/** @format */
'use strict';
//определим переменные для функцийи плагинов
let gulp = require('gulp'),
sass = require('gulp-sass'), //препроцессор
cssmin = require('gulp-cssmin'), //минификатор CSS
cleancss = require('gulp-clean-css'),
prefixer = require('gulp-autoprefixer'), //автоматическая расстановка вендорных префиксов
babel = require('gulp-babel'), //переводит js-файлы в формат, понятный даже тупому ослику(IE)ю Если точнее, конвертирует javascript стандарта ES6 в ES5
include = require('gulp-file-include'), //импорт одних файлов в другие (работает с HTML, SCSS/CSS и JS, но нужен он нам в основном для импорта HTML)
browserSync = require('browser-sync'), //сервер для отображения в браузере в режиме реального времени
rename = require('gulp-rename'), //переименовывает файлы, добавляет им префиксы и суффиксы
imagemin = require('gulp-imagemin'), //пережимает изображения
recompress = require('imagemin-jpeg-recompress'), //тоже пережимает, но лучше. Плагин для плагина
pngquant = require('imagemin-pngquant'),
// webp = require('gulp-webp'),
// webphtml = require('gulp-webp-html'),
// webpcss = require("gulp-webpcss"),
uglify = require('gulp-uglify'), //то же, что cssmin, только для js
concat = require('gulp-concat'), //склеивает css и js-файлы в один
del = require('del'), //удаляет указанные файлы и директории. Нужен для очистки перед билдом
ttf2woff = require('gulp-ttf2woff'), //конвертирует шрифты в веб-формат
ttf2woff2 = require('gulp-ttf2woff2'), //конвертирует шрифты в веб-формат
ttf2eot = require('gulp-ttf2eot'), //конвертирует шрифты в веб-формат
size = require('gulp-filesize'), //выводит в консоль размер файлов до и после их сжатия, чем создаёт чувство глубокого морального удовлетворения, особенно при минификации картинок
rsync = require('gulp-rsync'), //заливает файлы проекта на хостинг по ftp с заданными параметрами
sourcemaps = require('gulp-sourcemaps'); //рисует карту слитого воедино файла, чтобы было понятно, что из какого файла бралось
gulp.task('scss', function () {
//делаем из своего scss-кода css для браузера
return (
gulp
.src('src/scss/**/*.scss') //берём все файлы в директории scss и директорий нижнего уровня
.pipe(sourcemaps.init()) //инициализируем sourcemaps, чтобы он начинал записывать, что из какого файла берётся
.pipe(
sass({
outputStyle: 'compressed',
})
) //конвертируем scss в css и импортируем все импорты
.pipe(
rename({
suffix: '.min',
})
) //переименовываем файл, чтобы было понятно, что он минифицирован
.pipe(
prefixer({
//добавляем вендорные префиксы
overrideBrowserslist: ['last 8 versions'], //последние 8 версий, но можно донастроить на большее или меньшее значение
browsers: [
//список поддерживаемых браузеров и их версия - ВНИМАНИЕ! данная опция влияет только на расстановку префиксов и не гарантирут 100% работы сайта в этих браузерах.
'Android >= 4',
'Chrome >= 20',
'Firefox >= 24',
'Explorer >= 11',
'iOS >= 6',
'Opera >= 12',
'Safari >= 6',
],
})
)
.pipe(
cleancss({
compatibility: 'ie8',
level: {
1: {
specialComments: 0,
removeEmpty: true,
removeWhitespace: true,
},
2: {
mergeMedia: true,
removeEmpty: true,
removeDuplicateFontRules: true,
removeDuplicateMediaBlocks: true,
removeDuplicateRules: true,
removeUnusedAtRules: true,
},
},
})
)
// .pipe(webpcss())
.pipe(sourcemaps.write()) //записываем карту в итоговый файл
.pipe(gulp.dest('build/css')) //кладём итоговый файл в директорию build/css
.pipe(
browserSync.reload({
stream: true,
})
) //обновляем браузер
.pipe(size())
); //смотрим размер получившегося файла
});
//Далее будут похожие или полностью аналогичные функции, которые нет смысла расписывать. Смотрите по аналогии с вышеописанными.
gulp.task('style', function () {
//создаём единую библиотеку из css-стилей всех плагинов
return gulp
.src([
//указываем, где брать исходники
'node_modules/normalize.css/normalize.css',
'node_modules/swiper/swiper-bundle.min.css',
'node_modules/jQueryFormStyler/dist/jquery.formstyler.css',
'node_modules/jQueryFormStyler/dist/jquery.formstyler.theme.css',
])
.pipe(concat('libs.min.css')) //склеиваем их в один файл с указанным именем
.pipe(cssmin()) //минифицируем полученный файл
.pipe(gulp.dest('build/css')) //кидаем готовый файл в директорию
.pipe(size());
});
gulp.task('script', function () {
//аналогично поступаем с js-файлами
return gulp
.src([
//тут подключаем разные js в общую библиотеку. Отключите то, что вам не нужно.
'node_modules/jquery/dist/jquery.js',
'node_modules/swiper/swiper-bundle.min.js',
'node_modules/jQueryFormStyler/dist/jquery.formstyler.min.js',
])
.pipe(size())
.pipe(babel())
.pipe(concat('libs.min.js'))
.pipe(uglify())
.pipe(gulp.dest('build/js'))
.pipe(size());
});
gulp.task('minjs', function () {
//минифицируем наш main.js и перекидываем в директорию build
return gulp
.src('src/js/*.js')
.pipe(size())
.pipe(babel())
.pipe(uglify())
.pipe(
rename({
suffix: '.min',
})
)
.pipe(gulp.dest('build/js'))
.pipe(size());
});
gulp.task('js', function () {
//обновляем браузер, если в наших js файлах что-то поменялось
return gulp.src('src/js/**/*.js').pipe(
browserSync.reload({
stream: true,
})
);
});
gulp.task('html', function () {
//собираем html из кусочков
return (
gulp
.src(['src/**/*.html', '!src/components/**/*.html'])
.pipe(
include({
//импортируем файлы с префиксом @@. ПРефикс можно настроить под себя.
prefix: '@@',
basepath: '@file',
})
)
// .pipe(webphtml())
.pipe(gulp.dest('build/'))
.pipe(size())
.pipe(
browserSync.reload({
stream: true,
})
)
);
});
gulp.task('font-woff', function () {
//перекидываем шрифты из директории src в build, а заодно следим за новыми файлами, чтобы обновлять браузер, когда появляется шрифт
return gulp
.src('src/fonts/**/*.+(eot|svg|ttf|otf|woff|woff2)')
.pipe(ttf2woff())
.pipe(gulp.dest('build/fonts/'))
.pipe(
browserSync.reload({
stream: true,
})
);
});
gulp.task('font-woff2', function () {
//перекидываем шрифты из директории src в build, а заодно следим за новыми файлами, чтобы обновлять браузер, когда появляется шрифт
return gulp
.src('src/fonts/**/*.+(eot|svg|ttf|otf|woff|woff2)')
.pipe(ttf2woff2())
.pipe(gulp.dest('build/fonts/'))
.pipe(
browserSync.reload({
stream: true,
})
);
});
gulp.task('font-eot', function () {
//перекидываем шрифты из директории src в build, а заодно следим за новыми файлами, чтобы обновлять браузер, когда появляется шрифт
return gulp
.src('src/fonts/**/*.+(eot|svg|ttf|otf|woff|woff2)')
.pipe(ttf2eot())
.pipe(gulp.dest('build/fonts/'))
.pipe(
browserSync.reload({
stream: true,
})
);
});
// gulp.task('favicons', function(){ //генератор favicon для всех устройств. Запускается вручную отдельной командой. Генерирует фавиконки на все случаи жизни и файл favicons.html, в котором находятся подключения этих иконок. Скопируйте подключения в файлы проекта и удалите favicons.html Больше нужно для веб-приложений, потому что их ярлыки выносят на главный экран. Сайтам же достаточно закинуть и подключить одну favicon.ico Короче, если вы не уверены, что большинство пользователей мобильных устройств запихнут ярлык вашего сайта на главный экран и разрешат push-уведомления в телефоне, ваша фамилия не Цукерберг и не Дуров - вам этот таск, скорее всего не нужен.
// return gulp.src('src/img/favicon/favicon.png')
// .pipe(favgen({
// appName: 'My App',
// appShortName: 'App',
// appDescription: 'This is my application',
// developerName: 'Hayden Bleasel',
// developerURL: 'http://haydenbleasel.com/',
// background: '#020307',
// path: 'favicons/',
// url: 'http://haydenbleasel.com/',
// display: 'standalone',
// orientation: 'portrait',
// scope: '/',
// start_url: '/?homescreen=1',
// version: 1.0,
// logging: false,
// html: 'favicons.html',
// pipeHTML: true,
// replace: true,
// })
// )
// .pipe(gulp.dest('src/'))
// });
gulp.task('images', function () {
//пережимаем изображения и складываем их в директорию build
return gulp
.src('src/images/**/*.+(png|jpg|jpeg|gif|svg|ico|webp)')
.pipe(size())
.pipe(
imagemin([
recompress({
//Настройки сжатия изображений. Сейчас всё настроено так, что сжатие почти незаметно для глаза на обычных экранах. Можете покрутить настройки, но за результат не отвечаю.
loops: 4, //количество прогонок изображения
min: 80, //минимальное качество в процентах
max: 100, //максимальное качество в процентах
quality: 'high', //тут всё говорит само за себя, если хоть капельку понимаешь английский
use: [pngquant()],
}),
imagemin.gifsicle(), //тут и ниже всякие плагины для обработки разных типов изображений
imagemin.optipng(),
imagemin.svgo(),
])
)
.pipe(gulp.dest('build/images'))
.pipe(
browserSync.reload({
stream: true,
})
)
.pipe(size());
});
// gulp.task("webp", function () {
// return gulp
// .src("src/images/**/*.+(png|jpg|jpeg|gif|svg|ico|webp)")
// .pipe(size())
// .pipe(webp({
// quality: 75,
// method: 6,
// }))
// .pipe(gulp.dest("build/images"))
// .pipe(
// browserSync.reload({
// stream: true,
// }),
// )
// .pipe(size())
// });
gulp.task('deletefonts', function () {
//задачи для очистки директории со шрифтами в build. Нужна для того, чтобы удалить лишнее.
return del.sync('build/fonts/**/*.*');
});
gulp.task('deleteimg', function () {
//аналогично предыдущей, но с картинками.
return del.sync('build/img/**/*.*');
});
gulp.task('watch', function () {
//Следим за изменениями в файлах и директориях и запускаем задачи, если эти изменения произошли
gulp.watch('src/scss/**/*.scss', gulp.parallel('scss'));
gulp.watch('src/**/*.html', gulp.parallel('html'));
gulp.watch(
'src/fonts/**/*.*',
gulp.parallel('font-woff', 'font-woff2', 'font-eot')
);
gulp.watch('src/js/**/*.js', gulp.parallel('minjs', 'js'));
gulp.watch('src/images/**/*.*', gulp.parallel('images'));
});
gulp.task('deploy', function () {
//грузим файлы на хостинг по FTP
return gulp.src('build/**').pipe(
rsync({
root: 'build/', //откуда берём файлы
hostname: 'yourLogin@yourIp', //ваш логин на хостинге@IPхостинга
destination: 'sitePath', //папка, в которую будем загружать
//port: 25212, //порт, к которому пойдёт подключение. Нужна, если нестандартный порт
include: ['*.htaccess'], //файлы, которые нужно включить в передачу
exclude: ['**/Thumbs.db', '**/*.DS_Store'], //файлы, которые нужно исключить из передачи
recursive: true, //передавать все файлы и папки рекурсивно
archive: true, //режим архива
silent: false, //отключим ведение журнала
compress: true, //включим сжатие
progress: true, //выведем прогресс передачи в консоль
})
);
});
gulp.task('browser-sync', function () {
//настройки лайв-сервера
browserSync.init({
server: {
baseDir: 'build/', //какую папку показывать в браузере
},
browser: [''], //в каком браузере
//tunnel: " ", //тут можно прописать название проекта и дать доступ к нему через интернет. Работает нестабильно, запускается через раз. Не рекомендуется включать без необходимости.
//tunnel:true, //работает, как и предыдущяя опция, но присваивает рандомное имя. Тоже запускается через раз и поэтому не рекомендуется для включения
host: '192.168.0.104', //IP сервера в локальной сети. Отключите, если у вас DHCP, пропишите под себя, если фиксированный IP в локалке.
});
});
gulp.task(
'default',
gulp.parallel(
'browser-sync',
'watch',
'scss',
'style',
'script',
'minjs',
'html',
'font-woff',
'font-eot',
'font-woff2',
'images'
)
); //запускает все перечисленные задачи разом