Живая перезагрузка

Живая перезагрузка — это техника в веб-разработке, которая позволяет разработчику видеть результат своего кода без обновления браузера.

В традиционном процессе вы должны нажать F5 или кнопку Обновить в своём браузере, чтобы попросить его обновить внесённые изменения. Это заставляет вас поочерёдно переключаться между редактором и браузером. Один раз, два, три раза и больше. Вы можете заметить, что эта привычка может оказаться очень утомительной и трудоёмкой.

Цель живой перегрузки — избежать ручной работы. Каждый раз, когда вы нажимаете Ctrl + S или сохраняетесь, ваш браузер будет перезагружаться самостоятельно. Круто!

Существует приложение под названием liveReload, которое вы могли бы использовать в сочетании с плагином Google Chrome, чтобы обеспечить живую перезагрузку. Я попытался заставить его работать как на Linux, так и Windows, но не мог. Поэтому, пожалуйста, простите меня. Одно несомненно, сегодня этот плагин есть с Gulp (gulp-livereload) и вы можете его опробовать.

Я не единственный, у кого не всё хорошо с liveReload. Большинство людей, несомненно, сталкивались со многими трудностями, пытаясь использовать его, так что они создали ему полную замену: gulp-browserSync.

Живая перезагрузка с gulp-browserSync

BrowserSync является вероятно одним из самых полезных плагинов, который хотелось бы иметь разработчику. Он на деле даёт вам возможность запустить сервер, на котором вы можете выполнять свои приложения. Он заботится о перезагрузке ваших HTML/PHP-файлов. У него также есть возможность обновить/внедрить CSS и JavaScript-файлы в HTML и многое другое. С помощью этого плагина вы идёте исключительно вперёд.

Теперь посмотрим, как это работает. Перейдите в папку проекта и установите плагин browser-sync так:

npm install --save-dev browser-sync

Включите его в файл gulpfile.js:

var browserSync = require('browser-sync');

Функция перезагрузки BrowserSync называется reload(). Давайте вызовем её и сохраним в переменной, просто для понятности.

var reload      = browserSync.reload;

Обратите внимание, что там, где я использую reload() вы также можете использовать browserSync.reload().

Задайте переменную paths вроде этого:

var paths = {
  html:['index.html'],
  css:['main.scss'],
  script:['script.coffee']
};

Эти файлы мы отслеживаем на любые изменения.

Мы создали задачу для файлов Sass и JavaScript, теперь давайте добавим одну для HTML-файлов.

gulp.task('html', function(){
  gulp.src(paths.html)
  .pipe(reload({stream:true}));
});

Всё что делает эта задача — пропускает наш HTML-файл через функцию reload() из browser-sync. Если вы, к примеру, используете jade то могли бы компилировать его до перезагрузки.

Делаем то же самое с нашими существующими задачами:

// CSS
gulp.task('mincss', function(){
  return gulp.src(paths.css)
    .pipe(sass().on('error', sass.logError))
    .pipe(minifyCss())
    .pipe(gulp.dest('main'))
    .pipe(reload({stream:true}));
});

// JavaScript
gulp.task('scripts', function(){
  return gulp.src(paths.script)
    .pipe(coffee())
    .pipe(gulp.dest('js'))
    .pipe(reload({stream:true}));
});

browser-sync нужно знать расположение файлов, которые мы перезагружаем/синхронизируем и запустить мини-сервер основанный на этом; порт для прослушивания; прокси, если возможно и др. Посмотрите все варианты здесь.

Давайте настроим browser-sync и предоставим ему всю информацию.

gulp.task('browserSync', function() {
  browserSync({
    server: {
      baseDir: "./"
    },
    port: 8080,
    open: true,
    notify: false
  });
});

Обратите внимание, что если вы не указали точный номер порта, browser-sync будет использовать порт 3000 по умолчанию.

Теперь добавьте эту задачу в задачу watcher:

gulp.watch(paths.html, ['html']);

И, наконец, подретушируем задачу default:

gulp.task('default', ['watcher', 'browserSync']);

Окончательно файл gulpfile.js должен выглядеть следующим образом:

var gulp        = require('gulp');
var minifyCss   = require('gulp-minify-css');
var coffee      = require('gulp-coffee');
var sass        = require('gulp-sass');
var notify      = require('gulp-notify');
var browserSync = require('browser-sync');
var reload      = browserSync.reload;

var paths = {
  html:['index.html'],
  css:['main.scss'],
  script:['script.coffee']
};

gulp.task('mincss', function(){
  return gulp.src(paths.css)
    .pipe(sass().on('error', sass.logError))
    .pipe(minifyCss())
    .pipe(gulp.dest('main'))
    .pipe(reload({stream:true}));
});

// ////////////////////////////////////////////////
// HTML 
// ///////////////////////////////////////////////
gulp.task('html', function(){
  gulp.src(paths.html)
  .pipe(reload({stream:true}));
});

// ////////////////////////////////////////////////
// Browser-Sync
// // /////////////////////////////////////////////
gulp.task('browserSync', function() {
  browserSync({
    server: {
      baseDir: "./"
    },
    port: 8080,
    open: true,
    notify: false
  });
});

gulp.task('scripts', function(){
  return gulp.src(paths.script)
    .pipe(coffee())
    .pipe(gulp.dest('js'))
    .pipe(reload({stream:true}));
});

gulp.task('watcher',function(){
  gulp.watch(paths.css, ['mincss']);
  gulp.watch(paths.script, ['scripts']);
  gulp.watch(paths.html, ['html']);
});

gulp.task('default', ['watcher', 'browserSync']);

После этого перейдите в папку проекта, если вы ещё не там, и запустите gulp. Сделайте несколько изменений в HTML или Sass-файле и наблюдайте магию Gulp! Если всё пойдёт хорошо, в консоли у вас должно быть что-то вроде следующего.

Browser-sync и PHP-файлы

Измените файл index.html на index.php и подправьте пути так:

var paths = {
  html:['index.php'],
  css:['main.scss'],
  script:['script.coffee']
};

Это предполагает, что вы хотите работать с PHP, а не только с HTML. Перейдите к командной строке, остановите текущий процесс через Ctrl + C, а затем запустите gulp снова.

Gulp выполнит ваше приложение на http://localhost:8080, но вы увидите только это на странице:

Cannot GET /

Помните, перед выполнением любых инструкций PHP, вам нужен сервер PHP. Так что через эту ошибку Gulp пытается сказать нам, что никакого PHP-сервера не найдено.

Всё, что нам нужно сейчас сделать — это запустить сервер PHP вместе с нашими задачами. Для этого мы используем плагин gulp-connect-php.

Запуск PHP-сервера по требованию с browserSync

Прежде всего, начнём с установки плагина gulp-connect-php, который нам поможет.

npm install --save-dev gulp-connect-php

Теперь включим его в gulpfile.js:

var connectPHP = require('gulp-connect-php');

Добавим задачу php:

gulp.task('php', function(){
  connectPHP.server({ base: './', keepalive:true, hostname: 'localhost', port:8080, open: false});
});

Подробнее о настройках gulp-connect-php читайте здесь. Поскольку мы можем установить port, baseDir и другие параметры из настроек PHP-сервера, мы можем модифицировать нашу задачу browserSync и сделать её легче:

gulp.task('browserSync', function() {
  browserSync({
    proxy:'127.0.0.1',
    port:8080
  });
});

Обратите внимание: я создал сервер не из browserSync, а из PHP. Скорее создал прокси для browserSync.

Окончательный файл должен выглядеть следующим образом:

var gulp        = require('gulp');
var minifyCss   = require('gulp-minify-css');
var coffee      = require('gulp-coffee');
var sass        = require('gulp-sass');
var notify      = require('gulp-notify');
var browserSync = require('browser-sync');
var reload      = browserSync.reload;
var connectPHP = require('gulp-connect-php');

// ////////////////////////////////////////////////
// Пути к исходным файлам
// они немного изменились
// ///////////////////////////////////////////////
var paths = {
  html:['./*.php'],
  css:['./*.scss'],
  script:['./*.coffee']
};

gulp.task('mincss', function(){
  return gulp.src(paths.css)
    .pipe(sass().on('error', sass.logError))
    .pipe(minifyCss())
    .pipe(gulp.dest('main'))
    .pipe(reload({stream:true}));
});

// ////////////////////////////////////////////////
// HTML
// ///////////////////////////////////////////////
gulp.task('html', function(){
  gulp.src(paths.html)
  .pipe(reload({stream:true}));
});

// ////////////////////////////////////////////////
// Browser-Sync
// // /////////////////////////////////////////////
gulp.task('browserSync', function() {
  browserSync({
    proxy:'127.0.0.1',
    port:8080
  });
});

// /////////////////////////////////////////////////
// PHP
// ////////////////////////////////////////////////
gulp.task('php', function(){
  connectPHP.server({ base: './', keepalive:true, hostname: 'localhost', port:8080, open: false});
});

gulp.task('scripts', function(){
  return gulp.src(paths.script)
    .pipe(coffee())
    .pipe(gulp.dest('js'))
    .pipe(reload({stream:true}));
});

gulp.task('watcher',function(){
  gulp.watch(paths.css, ['mincss']);
  gulp.watch(paths.script, ['scripts']);
  gulp.watch(paths.html, ['html']);
});

gulp.task('default', ['watcher', 'browserSync', 'php']);

Опробуйте это.

Резюме

Живая перезагрузка — это интересная функция, с которой вы действительно можете наслаждаться Gulp. По-прежнему есть несколько способов написания задач и особенно, когда сочетается browserSync и gulp-connect-php. Я приглашаю вас посмотреть соответствующие сайты ради новых идей.

Автор и редакторы

Автор: Ахмед Салифу Амиду
Последнее изменение: 06.04.2016
Редакторы: Влад Мержевич