Ещё один способ версионирования стилей сайта

Ещё один способ версионирования стилей сайта

Статьи

Проект здорового человека должен развиваться — это простая данность. Сайты в развитии меняются, появляются новые функции, дошлифовывается прежний визуал. Да те же самые шрифты нет-нет, да просят поиграть с ними.

Самое главное в этих изменениях — чтобы пользователи не встретились с артефактами этих изменений, когда разметка уже поменялась, а стили остались в кеше браузера, и на экране перед нами нарисовалось что-то из русского авангарда начала 20 века.

Когда мы создаём приложение на каком-либо js-фреймворке, где процессом сборки руководить кто-то вроде Webpack’a, то в этом случае это не проблема, а просто незнание возможностей.

А вот когда стили и javascript — это просто дополнение (ха-ха) к html, то здесь уже приходится применять смекалку. Где-то нам достаточно всего лишь поставить плагин, который будет подколючать собираемые стили и скрипты к нужным файлам, а в иных случаях нужно проявить смекалку. Или смирение, каждый раз после сборки меняя префиксы для подключаемых файлов, типа такого:

// Вот на этой странице, например, вот так подключен стиль
<link rel="stylesheet" href="https://anatolykulikov.ru/wp-content/themes/akulikov/css/style.css?v=2">

Сегодняшний мой небольшой пост будет про лень и смекалку. Итак, дано:

  • сайт на WordPress, где время от времени происходят дополнения по стилю и функционалу, т.е. меняются css и js файлы
  • gulp, который собирает, сшивает, обрабатывает и делает всякое разное с ними
  • необходимость автоматизировать процесс изменения версий этих файлов

Здесь сразу понятно, что использовать магию хешеподобных стилей, которые у каждой сборки разные — не получится, т.к. вся вёрстка генерируется с помощью php. Да и подключать файлы у WordPress правильно всё же через специальное событие wp_enqueue_scripts, которое обычно лежит где-то в functions.

Поэтому тут или вручную проставлять ?v=xxx, либо то, что мне пришло в голову.

Суть подхода

Заключается в том, что обычно используется два режима работы:

  • разработка — стили/скрипты пересобираются после каждого изменения, чтобы не отвлекатся на всякие npm run dev
  • сборка — запускается перед доставкой готового кода на сервер

И вот как раз при сборке нам было бы классно сообщить как-то остальной системе, что у нас обновились файлики. Как это можно сделать? Да просто создать файл, где эта информация будет отражена.

Для начала нам в самом gulp нужно создать такого типа команду:

gulp.task('version', function (done) {
    const data = "<?php return '" + JSON.stringify(Date.now()) + "';";
    fs.writeFileSync(filepath + 'version.php', data);
    done();
});

Что здесь происходит — мы просто генерируем php-файл с названием version, который нам возвращает строку, содержащую метку времени, когда собственно этот файл и был создан. Можно, конечно, какую-нибудь покруче функцию придумать, но в принципе этого вполне достаточно.

Теперь, когда мы поместили наш файл в место, указанное в переменной filepath, нам нужно передать из него информацию в WordPress. Напишем для этого простую функцию (в functions.php):

function versionPrefix(): string {
    $prefix = '';
    if(file_exists(get_theme_file_path('version.php'))) {
        $prefix = include(get_theme_file_path('version.php'));
    }
    return $prefix;
}

Эта функция проверяет наличие файла там, где мы его ожидаем найти, и если его обнаруживаем, то возвращаем его содержимое.

Новую функцию мы ипользуем в стандартном подключении стилей и скриптов там, где для этих файлов можно указать версию:

add_action('wp_enqueue_scripts', 'add_style_and_scripts');
function add_style_and_scripts() {
	wp_enqueue_style('ourstyles', get_template_directory_uri() . '/build/style.css', [], versionPrefix());
	wp_enqueue_script('ourscripts', get_template_directory_uri() . '/build/script.js', [], versionPrefix(), true);
}

Здесь сразу хочу пояснить, почему используется get_template_directory_uri(), a не get_stylesheet_uri() — штука в том, что get_stylesheet_uri возвращает путь к файлу style.css, где WordPress хранит много важной информации про тему и без этого файла никак. В наших же файлах хочется подтянутости, минифицированности и отсутствия всяких комментариев. Поэтому собираемый файл или будет по-другому назван, или просто будет находится в другом месте.

Всё готово — теперь каждый раз при сборке новых стилей/скриптов нам будет автоматом подставлятся свежий префикс, доставляя в браузеры пользователей свеженькое.

На этом всё. Надеюсь, что этот простой фокус сможет вам помочь в деле разработки сайтов.

Анатолий Куликов

Анатолий Куликов

Автор блога, веб-разработчик
  • at sign
  • vk logo