larakit/lk-staticfiles

[Larakit] Библиотека для Laravel для управления статикой (сборка в один файл, сжатие JS/CSS, добавление хэша в URL для сброса кэша браузера)

Maintainers

👁 larakit

Package info

github.com/larakit/lk-staticfiles

pkg:composer/larakit/lk-staticfiles

Statistics

Installs: 1 752

Dependents: 25

Suggesters: 0

Stars: 0

Open Issues: 1

dev-master 2018-03-01 03:36 UTC

Requires (Dev)

None

Suggests

None

Provides

None

Conflicts

None

Replaces

None

MIT 1ee718b1f3a00c29c46b06c2f501413599b0335a

  • Alexey Berdnikov <aberdnikov.woop@gmail.com>

cssJSlaravellaravel 5larakitlarastatic

This package is auto-updated.

Last update: 2026-06-16 05:30:22 UTC


README

👁 Total Downloads
👁 Latest Stable Version
👁 Latest Unstable Version
👁 License
👁 License
👁 Gitter
#[Larakit Staticfiles] Библиотека для управления статикой (сборка в один файл, сжатие JS/CSS, добавление хэша в URL для сброса кэша браузера)

Модуль был портирован с модуля для фреймворка Kohana, который служил мне верой и правдой более 5 лет ( и модуль, и Kohana :) ) (подробнее я описывал его тут https://habrahabr.ru/post/112852/)

Примечание: будем считать, что проект Laravel у вас уже создан

###1. Файл с правилами подключения статики

Для порядка добавим подключаемые стили и скрипты вынесем в отдельный файл, например

./app/Http/staticfiles.php

Затем в файле

./app/Http/routes.php

подключим его

<?php

Route::get('/', function () {
 return view('welcome');
});

require app_path('Http/staticfiles.php');

###2. Установим пакет

$composer require larakit/lk-staticfiles

Далее нужно либо воспользоваться рекомендациями пакета https://github.com/larakit/lk-boot и произвести две правки

./app/Http/Kernel.php

и

./config/app.php

либо руками зарегистрировать в

./config/app.php

сервис-провайдер "Larakit\StaticFiles\LarakitServiceProvider"

<?php

return [
 ...
 'providers' => [
 ...,
 Larakit\StaticFiles\LarakitServiceProvider::class
 ],
 ...
];

Проверим что все хорошо, для этого наберем в консоли команду:

php artisan | grep larastatic

Если вы видите текст:

larastatic
 larastatic:deploy Выложить статику из зарегистрированных пакетов в DOCUMENT_ROOT

поздравляю, пакет был корректно установлен и инициализирован!

###3. Заполним staticfiles.php инструкциями по подключению CSS

Для начала посмотрим содержимое по-умолчанию главной страницы после установки фреймворка

👁 Image

и постараемся воспроизвести его при помощи данного пакета

<?php
\Larakit\StaticFiles\Css::instance()
 ->add('https://fonts.googleapis.com/css?family=Lato:100')
 ->addInline('
 html, body {
 height: 100%;
 }

 body {
 margin: 0;
 padding: 0;
 width: 100%;
 display: table;
 font-weight: 100;
 font-family: "Lato";
 }

 .container {
 text-align: center;
 display: table-cell;
 vertical-align: middle;
 }

 .content {
 text-align: center;
 display: inline-block;
 }

 .title {
 font-size: 96px;
 } 
');

Чтобы добавленные стили и скрипты вставились во все страницы сайта надо в вашем шаблоне прописать вызов

👁 Image

Получилось!

Примечание: результаты выполнения

\Larakit\StaticFiles\Css::instance()
 ->add('"https://fonts.googleapis.com/css?family=Lato:100')
 ->addInline('
 html, body {
 height: 100%;
 }
');

и

\Larakit\StaticFiles\Css::instance()
 ->add('"https://fonts.googleapis.com/css?family=Lato:100');
 
\Larakit\StaticFiles\Css::instance()
 ->addInline('
 html, body {
 height: 100%;
 }
');

будут одинаковы.

###4. Работа с JS Она не намного сложнее работы с JS.

Только помимо двух методов добавляющих стили по ссылке или методом inline-вставки как в CSS, здесь есть еще два метода:

  • добавление onLoad
  • добавление Noscript

Чтобы продемонстрировать функционал JS-менеджера - дополним пример: сделаем так, чтобы

  • после загрузки страницы вылетал алерт "привет!"
  • загружалась яндекс карта
  • при отключенном javascript показывался текст "Упс, включи JS!"

Напомню, все это мы делаем в файле

./app/Http/staticfiles.php

Итак, дополним его согласно новым требованиям

\Larakit\StaticFiles\Js::instance()
 //подключим jQuery
 ->add('https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js')
 //подключим API яндекс карт
 ->add('//api-maps.yandex.ru/2.1/?lang=ru_RU')
 ->addInline('
 var myMap;
 // Дождёмся загрузки API и готовности DOM.
 ymaps.ready(init);
 function init () {
 // Создание экземпляра карты и его привязка к контейнеру с
 // заданным id ("map").
 myMap = new ymaps.Map("map", {
 // При инициализации карты обязательно нужно указать
 // её центр и коэффициент масштабирования.
 center: [55.76, 37.64], // Москва
 zoom: 10
 }, {
 searchControlProvider: "yandex#search"
 });
 } 
')
 //добавим привествие при загрузке страницы
 ->addOnload('alert("привет!")')
 //добавим сообщение при выключенном JS
 ->addNoscript('Упс, включи JS!');
//добавим необходиеы стили для карты
\Larakit\StaticFiles\Css::instance()
 ->addInline('
 #map {
 width: 100%;
 height: 200px;
 } 
');

Дополним и сам шаблон:

  • добавим вызов функции вставки скриптов
  • добавим контейнер для карты

👁 Image

Обновляем страницу:

  1. alert при загрузке страницы вылетел

👁 Image

  1. Яндекс.карта появилась

👁 Image

  1. отключаем javascript в браузере и перезагружаем страницу - справа вверху видим надпись "Упс, включи JS!"

👁 Image

Смотрим как были добавлены скрипты: 👁 Image

###5. Способы распространения статики Их всего три:

  1. использование внешних ресурсов (простое подключение)
  2. использование статики из DOCUMENT_ROOT (простое подключение)
  3. использование статики из vendor-пакетов или node_modules (требует выкладки в DOCUMENT_ROOT)

Так вот для третьего пункта и существует команда, которая производит выкладку пакетов в директорию

./public/packages/...

запускается она так:

php artisan larastatic:deploy 

и после ее запуска будет произведена выкладка статики для каждого зарегистрированного пакета

Как использовать готовые пакеты со статикой:

  • заходите на github.com и вписываете в поле поиска "lk-staticfiles"
  • находите пакет, например, https://github.com/larakit/sf-bootstrap
  • внутри него уже есть подробнейшая документация по использованию
  • подключаете его в композере
  • и все!

он сам пропишется где надо и будет работать.

Понимаете? Никаких тебе танцев в написанием gulp/grunt-правил для каждого проекта. Просто прописал в composer записимость, он установился и автоматически подключился на страницу.

Причем с возможностью отключения/включения на определенных роутах по маске (см. ниже)

###6. Встроенные возможности по клиентской оптимизации

В пакете предусмотрены следующие возможности:

  • минимизация CSS [inline] - по умолчанию включена только на окружении "production"
  • минимизация CSS [external] - по умолчанию включена только на окружении "production"
  • минимизация JS [inline] - по умолчанию включена только на окружении "production"
  • минимизация JS [external] - по умолчанию включена только на окружении "production"
  • минимизация JS [onload] - по умолчанию включена только на окружении "production"
  • сборка всех CSS в один билд-файл [inline] - по умолчанию включена только на окружении "production"
  • сборка всех CSS в один билд-файл [external] - по умолчанию включена только на окружении "production"
  • сборка всех JS в один билд-файл [inline] - по умолчанию включена только на окружении "production"
  • сборка всех JS в один билд-файл [external] - по умолчанию включена только на окружении "production"
  • сборка всех JS в один билд-файл [onload] - по умолчанию включена только на окружении "production"
  • изменение хоста, с которого раздается статика - по умолчанию пустое значение, т.е. текущий домен

А теперь рассмотрим все по отдельности: для этого добавим еще стили и скрипты, размещенные внутри проекта

  • /js/js.js
  • /css/css.css
<?php
\Larakit\StaticFiles\Css::instance()
 ->add('https://fonts.googleapis.com/css?family=Lato:100')
 ->add('/css/css.css')
 ->add('/css/css2.css')
 ->add('/css/css3.css')
 ->add('/css/css4.css')
 ->add('/css/css5.css')
 ->addInline('
 html, body {
 height: 100%;
 }

 body {
 margin: 0;
 padding: 0;
 width: 100%;
 display: table;
 font-weight: 100;
 font-family: "Lato";
 }

 .container {
 text-align: center;
 display: table-cell;
 vertical-align: middle;
 }

 .content {
 text-align: center;
 display: inline-block;
 }

 .title {
 font-size: 96px;
 } 
');
\Larakit\StaticFiles\Js::instance()
 //подключим jQuery
 ->add('https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js',null,true)
 //подключим API яндекс карт
 ->add('//api-maps.yandex.ru/2.1/?lang=ru_RU',null,true)
 ->add('/js/js.js')
 ->add('/js/js2.js')
 ->add('/js/js3.js')
 ->add('/js/js4.js')
 ->add('/js/js5.js')
 ->addInline('
 var myMap;
 // Дождёмся загрузки API и готовности DOM.
 ymaps.ready(init);
 function init () {
 // Создание экземпляра карты и его привязка к контейнеру с
 // заданным id ("map").
 myMap = new ymaps.Map("map", {
 // При инициализации карты обязательно нужно указать
 // её центр и коэффициент масштабирования.
 center: [55.76, 37.64], // Москва
 zoom: 10
 }, {
 searchControlProvider: "yandex#search"
 });
 } 
')
 //добавим привествие при загрузке страницы
 ->addOnload('alert("привет!")')
 //добавим сообщение при выключенном JS
 ->addNoscript('Упс, включи JS!');
//добавим необходимые стили для карты
\Larakit\StaticFiles\Css::instance()
 ->addInline('
 #map {
 width: 100%;
 height: 200px;
 } 
');

/js/js.js /js/js2.js /js/js3.js /js/js4.js /js/js5.js

confirm(
 "Выполнился скрипт js.js?"
);

/css/css.css /css/css2.css /css/css3.css /css/css4.css /css/css5.css

body{
 color : #EB6251;;
}

Сохраним показания YSlow перед началом оптимизации

Так выглядели подключенные стили до оптимизации

👁 Image

А так скрипты

👁 Image

###6.1 Включение сборки CSS и JS в билд-файлы Для этого в .env пропишем:

# включим сборку CSS [inline] в один файл
LARAKIT_STATIC_CSS_INLINE_BUILD=1

# включим сборку CSS [подключенные по ссылке] в один файл
LARAKIT_STATIC_CSS_EXTERNAL_BUILD=1

# включим сборку CSS [inline] в один файл
LARAKIT_STATIC_JS_INLINE_BUILD=1

# включим сборку CSS [подключенные по ссылке] в один файл
LARAKIT_STATIC_JS_EXTERNAL_BUILD=1

# включим сборку CSS [onload] в один файл
LARAKIT_STATIC_JS_ONLOAD_BUILD=1

Теперь код нашей странички стал намного компактнее:

👁 Image

###6.3 Исключение из билд-файла некоторых CSS и JS Мы видим, что в билды попали файлы, которые не надо собирать в билды, а значит они должны отдаваться именно из того места, откуда были подключены:

Установим для них параметр no_build в true:

  • в CSS это четвертый параметр
  • в JS это третий параметр
\Larakit\StaticFiles\Css::instance()
 ->add(
 //внешний стиль
 'https://fonts.googleapis.com/css?family=Lato:100',
 //media - условие использования, например "all" или "print"
 null, 
 //условие подключения, например "if IE 6"
 null,
 //no_build
 true
 )
 ...
;

\Larakit\StaticFiles\Js::instance()
 //подключим jQuery
 ->add(
 'https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js',
 //условие подключения, например "if IE 6"
 null,
 //no_build
 true
 )
 //подключим API яндекс карт
 ->add(
 '//api-maps.yandex.ru/2.1/?lang=ru_RU',
 //условие подключения, например "if IE 6"
 null,
 //no_build
 true
 )
 ...
;

Результат:

👁 Image

###6.2 Включение минимизации CSS и JS Для этого в .env пропишем:

LARAKIT_STATIC_CSS_INLINE_MIN=1
LARAKIT_STATIC_CSS_EXTERNAL_MIN=1

Добавим в .env еще инструкций:

LARAKIT_STATIC_CSS_INLINE_MIN=1
LARAKIT_STATIC_CSS_INLINE_MIN=1
LARAKIT_STATIC_CSS_EXTERNAL_MIN=1
LARAKIT_STATIC_JS_INLINE_MIN=1
LARAKIT_STATIC_JS_EXTERNAL_MIN=1
LARAKIT_STATIC_JS_ONLOAD_MIN=1

Выложим статику еще раз,

php artisan larastatic:deploy

чтобы были перегенерированы ссылки на подключаемую статику для сброса кэша браузеров

Продемонстрируем результаты работы на примере CSS

Было

👁 Image

Стало

👁 Image

Продемонстрируем результаты работы на примере CSS

Было

👁 Image

Стало

👁 Image

###6.3 Отдача статики с другого домена

Имитируем перенос статики на CDN, для этого создадим домен "st1.staticfiles" и сделаем его алиасом для домена "staticfiles".

Затем добавим в .env еще инструкций:

LARAKIT_STATIC_PREFIX=http://st1.staticfiles

Результат: 👁 Image

Смотрим показания YSlow перед началом оптимизации

👁 Image

А теперь снова запускаем YSlow для проверки результатов нашей оптимизации:

👁 Image

####Т.е. удалось поднять Overall performance score c 80 до 93

Смотрим показания YSlow перед началом оптимизации

👁 Image

А теперь снова запускаем YSlow для проверки результатов нашей оптимизации:

👁 Image

Результат был бы еще выше, если бы мы использовали полноценные большевесные стили и скрипты в большом количестве, а не несколько пустышек, взятых для примеров.

По-моему, не плохо для коробочного решения делающего это автоматически.

###7. Создание собственных пакетов

Ну и, пожалуй, самое главное: возможность оформлять свои пакеты. Сделаем два вида пакетов:

  • с использованием CDN
  • с распространением статики из пакета

Рекомендации:

  • (для удобного поиска на packagist) обязательно вписывайте следующие теги "laravel, lk-staticfiles"
  • (для удобного поиска на github) в Description репозитория на github вписывайте префикс "[Larakit][lk-staticfiles] "

👁 Image

###7.1 Создание собственных пакетов с использованием CDN

Создаем composer.json

{
 "name": "larakit/sf-bootstrap",
 "description": "sf-bootstrap",
 "keywords": [
 "larakit",
 "laravel",
 "laravel 5",
 "bootstrap",
 "lk-staticfiles"
 ], 
 "license": "MIT",
 "version": "3.3.6",
 "require": {
 "larakit/sf-jquery": "*"
 },
 "autoload": {
 "files": [
 "init.php"
 ]
 }
}

В разделе require укажите статические пакеты, от которых зависит ваш пакет (например, если вам нужен jQuery), а если таких нет впишите зависимость от текущего пакета

{
 "require":{
 "larakit/lk-staticfiles":"*"
 },
}

В автоподключаемый файл init.php впишите инструкции по подключению и снова укажите зависимости от пакетов, чтобы они были подключены до создаваемого пакета

<?php
\Larakit\StaticFiles\Manager::package('larakit/sf-bootstrap')
 ->usePackage('larakit/sf-jquery')
 ->js('//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js')
 ->css('//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css');

Собственно все! Для использования вам достаточно прописать в композер проекта "require": "/sf-ваш_пакет"

###7.2 Создание собственных пакетов с распространением статики из пакета Точно также создаем composer.json и init.php. Единственное отличие: в init.php прописываем директорию со статикой, откуда будет производится ее выкладка в DOCUMENT_ROOT из vendor.

<?php
\Larakit\StaticFiles\Manager::package('larakit/sf-larakit-js')
 
 //из этого относительного пути внутри пакета будет произведена выкладка
 ->setSourceDir('public')
 
 //обязательно подключить указанный зависимый пакет ПЕРЕД текущим пакетом
 ->usePackage('larakit/sf-jquery')
 
 //искать JS внутри директории SOurceDir
 ->jsPackage('js/larakit.js');

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

./vendor/larakit/sf-larakit-js/public

и выложено в

./public/packages/larakit/sf-larakit-js/

Сама выкладка напомню производится путем запуска команды:

php artisan larastatic:deploy

Эта команда выполняет следующие действия:

  • выкладывает в ./public/packages/ все зарегистрированные файлы из vendor пакетов
  • обновляет хэш статики, чтобы сбросился кэш браузера (изменяется URL подключаемых стилей и скриптов)

###8. Правила включения/выключения пакетов В процессе работы может возникнуть такая необходимость как точечное отключение или включение используемых пакетов. Например, нам надо отключить пакет "larakit/sf-jquery" в админке. Так как мы делали все роуты админки с префиксом "admin.", то у нас есть сейчас три роута:

  • admin
  • admin.users
  • admin.news
  • admin.pages

Инструкциию для управления подключением пакетов пишем в файле ./app/Http/staticfiles.php:

####8.1 Отключение пакета jQuery только на главной странице админки

\Larakit\StaticFiles\Manager::package('larakit/sf-jquery')
 ->setExclude('admin');

####8.2 Отключение пакета jQuery только на внутренних страницах админки

\Larakit\StaticFiles\Manager::package('larakit/sf-jquery')
 ->setExclude('admin.*');

####8.3 Отключение пакета jQuery во всей админке

\Larakit\StaticFiles\Manager::package('larakit/sf-jquery')
 ->setExclude('admin*');

####8.4 Отключение пакета jQuery во всей админке, кроме страницы управления пользователями

\Larakit\StaticFiles\Manager::package('larakit/sf-jquery')
 ->setExclude('admin*')
 ->setInclude('admin.users');

####8.5 Отключение пакета jQuery на всем сайте, кроме страницы управления пользователями

\Larakit\StaticFiles\Manager::package('larakit/sf-jquery')
 ->setExclude('*')
 ->setInclude('admin.users');

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

###... ###Profit!