Browser-sync на gulp перезагружает браузер два раза, но изменения не видны?

Здравствуйте. Вот что использую - https://github.com/Zoxon/gulp-front/blob/master/gu...
История такая, есть файлы jade, есть папка blocks где хранятся partial которые используются как include и extands в файлах jade. Когда редактриуешь некоторые файлы jade, то браузер обновляется два раза, изменений в браузере нет, приходится в ручную третий раз обновлять для результата. В консоли все ок

[15:55:27] Starting 'jade'...
[15:55:27] Finished 'jade' after 1.96 ms


Однако когда редактируешь, например index.jade с таким содержанием, все ок! После второго рефреша изменения видны:

В чем может быть проблема? Помогите пожалуйста
  • Вопрос задан
  • 2150 просмотров
Решения вопроса 1
Zoxon
@Zoxon
Веб-разработчик
Не знаю какая версия у в вас используется, но в общем починить можно так.
Пришлось обновить конфиг browserSync по текущей версии, он отличается.
Затем заменить gulp.watch на пакет gulp-watch, и использовать run-sequence для запуска тасков, и добавить инкрементал билд для jade, по тому как сборка длилась очень долго.
Получился такой gulpfile.js

'use strict';

// Инициализируем плагины
var gulp = require('gulp'),
	jade = require('gulp-jade'),
	stylus = require('gulp-stylus'),
	autoprefixer = require('autoprefixer-stylus'),
	imagemin = require('gulp-imagemin'),
	browserSync = require('browser-sync').create(),
	cssbeautify = require('gulp-cssbeautify'),
	gutil = require('gulp-util'),
	newer = require('gulp-newer'),
	include = require('gulp-include'),
	rename = require("gulp-rename"),
	uglify = require('gulp-uglify'),
	imageminPngquant = require('imagemin-pngquant'),
	csscomb = require('gulp-csscomb'),
	csso = require('gulp-csso'),
	gulpFilter = require('gulp-filter'),
	plumber = require('gulp-plumber'),
	del = require('del'),
	runSequence = require('run-sequence'),
	watch = require('gulp-watch'),
	gulpZip = require('gulp-zip'),
	nodePath = require('path'),
	jadeInheritance = require('gulp-jade-inheritance'),
	gulpif = require('gulp-if'),
	cached = require('gulp-cached'),
	changed = require('gulp-changed'),
	filter = require('gulp-filter');

// Функция обработки ошибок
var errorHandler = function(err) {
	gutil.log([(err.name + ' in ' + err.plugin).bold.red, '', err.message, ''].join('\n'));

	if (gutil.env.beep) {
		gutil.beep();
	}

	this.emit('end');
};

var correctNumber = function correctNumber(number) {
	return number < 10 ? '0' + number : number;
};

// Return timestamp
var getDateTime = function getDateTime() {
	var now = new Date();
	var year = now.getFullYear();
	var month = correctNumber(now.getMonth() + 1);
	var day = correctNumber(now.getDate());
	var hours = correctNumber(now.getHours());
	var minutes = correctNumber(now.getMinutes());
	return year + '-' + month + '-' + day + '-' + hours + minutes;
};

// Имена папок
var config = {
	path: {
		source: 'source',
		dist: 'public',
		assets: 'assets',
		partials: 'blocks',
		js: 'js',
		css: 'css',
		images: 'img'
	}
};

// Настройки плагинов
var plugins = {
	browserSync: {
		options: {
			server: {
				baseDir: './public'
			}
		}
	},

	autoprefixer: {
		options: {
			browsers: [
					'last 2 version',
					'Chrome >= 20',
					'Firefox >= 20',
					'Opera >= 12',
					'Android 2.3',
					'Android >= 4',
					'iOS >= 6',
					'Safari >= 6',
					'Explorer >= 8'
				],
			cascade: false
		}
	},

	stylus: {
		options: {}
	},

	cssbeautify: {
		options: {
			indent: '	',
			autosemicolon: true
		}
	},

	jade: {
		options: {
			pretty: '\t',
			basedir: config.path.source
		}
	},

	jadeInheritance: {
		options: {basedir: config.path.source}
	},

	imagemin: {
		options: {
			optimizationLevel: 3,
			progressive: true,
			interlaced: true,
			svgoPlugins: [{removeViewBox: false}],
			use: [imageminPngquant()]
		}
	},

	rename: {
		options: {
			suffix: ".min"
		}
	}
}

// Пути к файлам
var path = {
	source: {
		html: [
			config.path.source + '/**/*.jade',
			'!' + config.path.source + '/' + config.path.partials + '/**/*.jade'
		],
		css: [
			config.path.source + '/**/*.styl',
			'!' + config.path.source + '/**/_*.styl',
			'!' + config.path.source + '/' + config.path.css + '/lib/**/*.styl'
		],
		img: config.path.source + '/' + config.path.images + '/**/*.{jpg,jpeg,png,gif,svg}',
		js: config.path.source + '/' + config.path.js + '/*.js',
		copy: config.path.assets + '/**/*'
	},

	dest: {
		html: config.path.dist,
		css: config.path.dist,
		img: config.path.dist + '/' + config.path.images,
		js: config.path.dist + '/' + config.path.js,
		copy: config.path.dist
	},

	watch: {
		html: config.path.source + '/**/*.jade',
		css: config.path.source + '/**/*.styl',
		img: config.path.source + '/' + config.path.images + '/**/*.{jpg,jpeg,png,gif,svg}',
		js: config.path.source + '/**/*.js',
		copy: config.path.assets + '/**/*'
	}
};

// Локальный сервер
gulp.task('browser-sync', function() {
	return browserSync.init(plugins.browserSync.options);
});

gulp.task('bs-reload', function (cb) {
	browserSync.reload();
});

// Собираем Stylus
gulp.task('stylus', function() {
	return gulp.src(path.source.css)
		.pipe(plumber({
			errorHandler: errorHandler
		}))
		.pipe(stylus({
			use: [
				autoprefixer(plugins.autoprefixer.options)
			]
		}))
		.pipe(cssbeautify(plugins.cssbeautify.options))
		.pipe(csscomb())
		.pipe(gulp.dest(path.dest.css))
		.pipe(browserSync.stream())
		.pipe(csso())
		.pipe(rename({suffix: '.min'}))
		.pipe(gulp.dest(path.dest.css));
});

// Собираем html из Jade
gulp.task('jade', function() {
	return gulp.src('source/**/*.jade')
		.pipe(plumber({
			errorHandler: errorHandler
		}))
		.pipe(cached('jade'))
		.pipe(gulpif(global.isWatching, jadeInheritance({basedir: 'source'})))
		.pipe(filter(function (file) {
			return !/source[\\\/]blocks/.test(file.path);
		}))
		.pipe(jade(plugins.jade.options))
		.pipe(gulp.dest(path.dest.html));
});

// Копируем и минимизируем изображения
gulp.task('images', function() {
	return gulp.src(path.source.img)
		.pipe(plumber({
			errorHandler: errorHandler
		}))
		.pipe(newer(path.dest.img))
		.pipe(imagemin(plugins.imagemin.options))
		.pipe(gulp.dest(path.dest.img));
});

// Копируем файлы
gulp.task('copy', function() {
	return gulp.src(path.source.copy)
		.pipe(plumber({
			errorHandler: errorHandler
		}))
		.pipe(newer(path.dest.copy))
		.pipe(gulp.dest(path.dest.copy))
		.pipe(gulpFilter(['**/*.js', '!**/*.min.js']))
		.pipe(uglify())
		.pipe(rename({suffix: '.min'}))
		.pipe(gulp.dest(path.dest.css));
});

// Собираем JS
gulp.task('plugins', function() {
	return gulp.src(path.source.js)
		.pipe(plumber({
			errorHandler: errorHandler
		}))
		.pipe(include())
		.pipe(gulp.dest(path.dest.js))
		.pipe(uglify().on('error', gutil.log))
		.pipe(rename(plugins.rename.options))
		.pipe(gulp.dest(path.dest.js));
});

// Отчистка папки public
gulp.task('cleanup', function(cb) {
	return del(config.path.dist + '/*', cb);
});

gulp.task('build-zip', function() {
	var prjName = 'dist';
	var rootFolderName = nodePath.basename(__dirname);

	if (!rootFolderName || typeof rootFolderName === 'string') {
		prjName = rootFolderName;
	}

	var datetime = '-' + getDateTime();
	var zipName = prjName + datetime + '.zip';

	return gulp.src('public/**/*')
		.pipe(gulpZip(zipName))
		.pipe(gulp.dest('zip'));
});

gulp.task('build', function (cb) {
	return runSequence(
		[
			'stylus',
			'jade',
			'images',
			'plugins',
			'copy'
		],
		cb
	);
});

gulp.task('zip', function (cb) {
	return runSequence(
		'cleanup',
		'build',
		'build-zip',
		cb
	);
});

gulp.task('watch', function () {
	global.isWatching = true;

	watch(path.watch.css, function() {
		return runSequence('stylus');
	});

	watch('source/**/*.jade', function() {
		return runSequence('jade', browserSync.reload);
	});

	watch(path.watch.img, function() {
		return runSequence('images', browserSync.reload);
	});

	watch(path.watch.js, function() {
		return runSequence('plugins', browserSync.reload);
	});

	watch(path.watch.copy, function() {
		return runSequence('copy', browserSync.reload);
	});

});

gulp.task('default', function (cb) {
	return runSequence(
		'build',
		'browser-sync',
		'watch',
		cb
	);
});


package.json
{
  "name": "gulp-front",
  "version": "3.0.0",
  "homepage": "https://github.com/Zoxon/gulp-front",
  "license": "MIT",
  "description": "Простой путь разработки с Jade и Stylus",
  "repository": {
    "type": "git",
    "url": "http://github.com/Zoxon/gulp-front.git"
  },
  "author": "Velicko Konstantin <zoxon.box@gmail.com> (http://github.com/Zoxon)",
  "licenses": {
    "type": "MIT",
    "url": "http://github.com/Zoxon/gulp-front/blob/master/license.txt"
  },
  "bugs": {
    "url": "http://github.com/Zoxon/gulp-front/issues"
  },
  "dependencies": {
    "autoprefixer-stylus": "^0.9.1",
    "browser-sync": "^2.10.0",
    "del": "^2.1.0",
    "gulp": "^3.9.1",
    "gulp-cached": "^1.1.0",
    "gulp-changed": "^1.3.0",
    "gulp-cssbeautify": "^0.1.3",
    "gulp-csscomb": "^3.0.6",
    "gulp-csso": "^1.0.1",
    "gulp-filter": "^3.0.1",
    "gulp-if": "^2.0.0",
    "gulp-imagemin": "^2.3.0",
    "gulp-include": "^2.0.2",
    "gulp-jade": "^1.1.0",
    "gulp-jade-inheritance": "^0.5.4",
    "gulp-newer": "^1.1.0",
    "gulp-plumber": "^1.0.1",
    "gulp-rename": "^1.2.2",
    "gulp-stylus": "^2.0.7",
    "gulp-uglify": "^1.5.1",
    "gulp-util": "^3.0.6",
    "gulp-watch": "^4.3.5",
    "gulp-zip": "^3.2.0",
    "imagemin-pngquant": "^4.2.0",
    "run-sequence": "^1.1.5"
  }
}


Если у вас старая структура папок (в корне папка assets, public, source), то попробуйте просто заменить эти файлы
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@Led
Front end developer
В таске jade уберите .pipe(reload({stream:true}));

Добавьте плагин run-sequence
и измените watcher для jade на подобное:
gulp.watch(path.watch.html, function(){runSequence('jade', reload)});
Ответ написан
Комментировать
@Haoss
html-верстальщик
такое начинает проявляться, когда количество макетов .jade становится много. На нескольких - обновляет сразу, без проблем, если много - тупо обновляет страницу несколько раз, но изменений нет, нажимаем вручную F5 и все изменения появляются. Решения пока не нашел. Возможно надо поставить плагин, который, обновляет только измененные файлы. Руки пока не дошли.
Ответ написан
@Bluorenge
Junior front-end developer
Можно добавить в browserSync опцию `reloadDebounce: 2000`. Но тогда будет задержка в 2 секунды перед перезагрузкой. Также возможно при увеличении количества страниц и такой задержки будет недостаточно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы