При работе с js хочется, чтобы браузер сам перезагружал страницу, так сказать делал hot reload, или, изменяя стили в css, они автоматически изменились в браузере (инъекция), как, например, это происходит при работе с React или Vue. Но как же этого добиться с Drupal? Есть много решений, но все они так или иначе используют browser-sync. Browser-sync - это пакет для nodejs, позволяющий синхронизировать несколько браузеров, а также делающий автоматическую перезагрузку страниц и инъекции стилей. Используя связку nodejs + gulp + browser-sync, мы будем делать всю эту магию вместе с Drupal. Мы не будем рассматривать как устанавливать nodejs, но он должен быть у вас установлен. Итак приступим!
Gulp
Gulp - замечательный таск-менеджер, гибкий и быстрый. Его роль заключается в отслеживании изменения файлов и последующем запуске browser-sync. Мы не будем подробно разбирать синтаксис конфигураций gulp, но вы подробнее можете ознакомиться в документации.
Установка
Изначально установим gulp-cli, чтобы иметь возможность вызывать gulp в терминале:
sudo npm install -g gulp-cli
Далее в директории проекта установим gulp локально:
sudo npm install -D gulp
Флаг
-D
вносит в package.json запись о Gulp в секцию devDependencies, отмечая, что пакет нужен только для разработки.
Установим browser-sync:
sudo npm i -D browser-sync
Настройка gulp и browser-sync
Создадим в корневой директории темы файл
gulpfile.js
. Будем использовать строгий режим в javascript. Добавим модули gulp и browser-sync.
'use strict';
const gulp = require('gulp');
const browserSync = require('browser-sync');
Приступим к добавлению задачи для gulp и настройки browser-sync. В функцию
gulp.task()
обернем вызов и настройки browser-sync.
gulp.task('sync', function() {
browserSync.init({
proxy: domain,
port: 8080
});
});
Разберем код выше поподробнее.
browserSync.init()
- это метод browser-sync для инициализации.
proxy
позволяет нам проксировать сервер по типу Apache или NGinx. Нужно указать домен или ip сервера. А
также нам нужно указать порт, по которому
сервер отдает сайт. О других настройках browser-sync можете почитать
тут.
Если мы вызовем в консоли
gulp sync
, он применит только последние изменения в файлах. Это неудобно. Нам
нужно вызывать browser-sync каждый раз как
мы изменяем файл. Будем делать это непосредственно вызовом метода
browserSync.watch()
. И теперь наш полный
gulpfile.js
выглядит так:
'use strict';
const settings = {
domain: 'd7.dev.zz',
port: '8080'
}
const gulp = require('gulp');
const browserSync = require('browser-sync');
gulp.task('sync', function() {
browserSync.init({
proxy: settings.domain,
port: settings.port
});
browserSync.watch('./css/*.css').on('change', browserSync.reload);
});
При изменении css gulp вызовет
browserSync.reload
, этот метод перезапустит browser-sync и добавит изменения в браузер.
Вместо
'./css/*.css'
подставьте путь к вашим css файлам. Продублировав строку с
browserSync.watch()
, можно добавлять отслеживание, например, javascript файлов:
browserSync.watch('./css/*.css').on('change', browserSync.reload);
browserSync.watch('./js/*.js').on('change', browserSync.reload);
Стоит отметить, что можно делать перезагрузку даже при изменении шаблонов тем. Нужно только добавить за ними "слежку".
Link CSS
Для корректной работы инъекций в браузер нам потребуется установить модуль Link CSS. Он есть для 7 и 8 версии. Зачем нужен этот модуль? В Drupal все css файлы добавляются на страницу через @import
тега <style>
, это не позволяет browser-sync делать инъекции. Модуль изменяет подход добавления css файлов, меняя его с @import
на тег <link>
.
Использование
Вызвав в консоли gulp sync
, мы запустим обработчик gulp, который будет следить за нашими файлами, и при их изменении делать перезагрузку или инъекцию в браузер. Browser-sync в это время будет проксировать сервер с Drupal'ом, и откроет отдельную вкладку в браузере, где будет реагировать на все изменения файлов. Так просто можно добавить hot reload для работы с Drupal.
Подскажите как почистить кэш с помощью gulp при редактировании twig шаблонов.
browserSync.watch('./templates/*.html.twig').on('change', browserSync.reload);