Laravel Elixir

Вступление

Laravel Elixir предоставляет удобный и гибкий API для исполнения базовых Gulp-задач в вашем приложении. Он поддерживает несколько популярных CSS и JavaScript препроцессоров и инструментов тестирования. Декларации css и js выстраиваются в виде цепочки, что позволяет удобно пользоваться функционалом Elixir. Например:

elixir(function(mix) {
    mix.sass('app.scss')
       .coffee('app.coffee');
});

Если даже вы не поняли сразу как начать работу со сборщиком Gulp и вашими медиа-файлами (assets), вы влюбитесь в Laravel Elixir. Однако вы не обязаны использовать его на этапе разработки вашего приложения. Вы сами можете выбрать инструменты для работы с вашими медиа-файлами (assets), ну и конечно вы можете не использовать их вовсе.

Установка и настройка

Установка Node

Перед вызовом Elixir, вы обязаны убедиться в том что Node.js установлен на вашем компьютере.

node -v

По умолчанию, все что вам нужно это Laravel Homestead; впрочем, если вы не используете Vagrant, тогда вы сможете легко установить Node.js пройдя по ссылке ссылка для скачивания Node.js.

Gulp

Далее, вам потребуется Gulp как глобальный NPM пакет:

npm install --global gulp

Если вы используете систему контроля версий, вы возможно захотите использовать npm shrinkwrap для блокировки ваших зависимостей NPM:

 npm shrinkwrap

Выполнив эту команду хотя бы один раз, вы можете свободно добавлять npm-shrinkwrap.json в контроль версий.

Laravel Elixir

Остался всего один шаг для установки Elixir! После свежей установки Laravel, вы обнаружите файл package.json в корневом каталоге. Взгляните на ваш файл composer.json, он описывает зависимости Node вместо PHP. Вы можете установить описанные зависимости используя команду:

npm install

Если вы ведете разработку на ОС Windows или вы запускаете вашу VM (виртуальную машину) на ОС Windows, возможно вам понадобится запустить команду npm install с ключом --no-bin-links, чтобы команда запустилась:

npm install --no-bin-links

Запуск Elixir

Elixir использует последнюю версию Gulp, поэтому для запуска задач Elixir'a вам всего лишь понадобится запустить команду gulp в вашей консоли (терминале). Добавление к команде ключа --production запустит Elixir с минифицированием ваших CSS стилей и Javascript скриптов:

// Запуск всех задач...
gulp

// Запуск всех задач и минификация CSS и JavaScript...
gulp --production

Наблюдение за изменением ваших медиа файлов и скриптов (assets)

Так как не очень удобно все время запускать команду gulp при изменении ваших файлов, вы можете запустить команду gulp watch. Эта команда будет продолжать работать в вашей консоли и наблюдать за любыми изменениями ваших файлов (assets). Когда произойдут изменения, новые файлы будут автоматически скомпилированы Elixir'ом:

gulp watch

Работа со стилями

Файл gulpfile.js в корневой папке вашего проекта содержит все задачи Elixir'a, которые могут быть связаны между собой, что позволяет настроить процесс сборки и компиляции ваших файлов (assets) так как вам надо.

Less

Для компиляции Less в CSS, вы можете использовать метод less. Метод less ожидает что ваши Less файлы находятся в папке resources/assets/less. По умолчанию задача скомпилирует файлы, указанные в примере, в CSS и сохранит в папку public/css/app.css:

elixir(function(mix) {
    mix.less('app.less');
});

Так же вы можете объединить несколько Less файлов в один CSS файл. И снова скомплированный CSS файл будет сохранен в папке public/css/app.css:

elixir(function(mix) {
    mix.less([
        'app.less',
        'controllers.less'
    ]);
});

Если вам потребуется изменить путь скомпилированного CSS файла, вы можете указать в методе less второй аргумент с нужным путем:

elixir(function(mix) {
    mix.less('app.less', 'public/stylesheets');
});

// Укажем собственное название скомпилированного файла...
elixir(function(mix) {
    mix.less('app.less', 'public/stylesheets/style.css');
});

Sass

Метод sass позволяет вам скомпилировать Sass в CSS. Предполагается что ваши Sass файлы лежат в resources/assets/sass, к примеру вы можете использовать метод sass так:

elixir(function(mix) {
    mix.sass('app.scss');
});

И снова, так же как при использовании метода less, Вы можете скомпилировать несколько Sass файлов в один CSS файл, и даже изменить папку для скомпилированного CSS:

elixir(function(mix) {
    mix.sass([
        'app.scss',
        'controllers.scss'
    ], 'public/assets/css');
});

Обычный CSS

Если вы просто хотите объединить некиие обычные CSS стили в один файл, вы можете использовать метод styles. Пути указанные в этом методе относительны к папке resources/assets/css и объединенный CSS файл будет сохранен, как public/css/all.css:

elixir(function(mix) {
    mix.styles([
        'normalize.css',
        'main.css'
    ]);
});

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

elixir(function(mix) {
    mix.styles([
        'normalize.css',
        'main.css'
    ], 'public/assets/css');
});

Source Maps (Карты ресурсов)

Source maps (Карты ресурсов) включены и работают из коробки. Для каждого скомпилированного файла вы найдете схожий *.css.map файл в папке скомпилированного файла. Эти карты позволяют вам преобразовать скомпилированные Less или Sass файлы для отладки в браузере.

Если вам не нужны source maps (карты ресурсов) для ваших CSS файлов, вы можете выключить их используя опцию:

elixir.config.sourcemaps = false;

elixir(function(mix) {
    mix.sass('app.scss');
});

Работа со скриптами

Elixir также предлагает несколько функций для работы с вашими JavaScript файлами, такими как компиляцию в ECMAScript 6, CoffeeScript, Browserify, минификацию, и простую конкатенацию в обычный JavaScript файлы.

CoffeeScript

Метод coffee может быть использован для компиляции CoffeeScript в обычный Javascript. Этот метод принимает строку или массив CoffeeScript файлов, которые относительны к папке resources/assets/coffee и генерирует единственный файл app.js в папке public/js:

elixir(function(mix) {
    mix.coffee(['app.coffee', 'controllers.coffee']);
});

Browserify

Вы можете смело использовать у себя в javascript-коде конструкции из ES6 и JSX - при помощи метода browserify Elixir скомпилирует их в стандартный javascript, который понимают все браузеры.

Эта задача предполагает что ваши скрипты расположены в папке resources/assets/js. Она сохранит скомпилированные файлы в папку public/js/main.js. Если вы хотите переопределить путь или название для скомпилированного файла, вы можете указать это в качестве второго аргумента:

elixir(function(mix) {
    mix.browserify('main.js');
});

// Укажем свое имя для скомпилированного файла...
elixir(function(mix) {
    mix.browserify('main.js', 'public/javascripts/main.js');
});

Browserify поддерживает Partialify и Babelify трансформеры, и вы можете легко выбирать и устанавливать их так как захотите:

npm install aliasify --save-dev
elixir.config.js.browserify.transformers.push({
    name: 'aliasify',
    options: {}
});

elixir(function(mix) {
    mix.browserify('main.js');
});

Babel

Метод babel используется для компиляции ECMAScript 6 and 7 и JSX в обычный JavaScript. Этот метод принимает массив файлов, расположенных относительно папки resources/assets/js и генерирует единственный файл all.js в папке public/js:

elixir(function(mix) {
    mix.babel([
        'order.js',
        'product.js',
        'react-component.jsx'
    ]);
});

Для указания нестадартной папки для сохранения вы как обычно можете указать свой путь в качестве второго аргумента. Принцип работы этого скрипта такая же как у метода mix.scripts(), за исключенем компиляции Babel.

Скрипты

Если у вас есть несколько JavaScript файлов и вы бы хотели объединить их в один файл, вы можете воспользоваться методом scripts.

Этот метод ожидает что все скрипты расположены в папке resources/assets/js, он по умолчанию сохранит объединенный файл JavaScript в папку public/js/all.js:

elixir(function(mix) {
    mix.scripts([
        'jquery.js',
        'app.js'
    ]);
});

Если вы хотите объединить ваши JavaScript файлы в разные файлы, вы можете вызвать метод scripts несколько раз. С помощью второго аргумента метода определите название файла для каждой операции объединения:

elixir(function(mix) {
    mix.scripts(['app.js', 'controllers.js'], 'public/js/app.js')
       .scripts(['forum.js', 'threads.js'], 'public/js/forum.js');
});

Если вам нужно объединить все файлы какой-либо папки, вы можете воспользоваться методом scriptsIn. Конечный файл будет сохранен по пути public/js/all.js:

elixir(function(mix) {
    mix.scriptsIn('public/js/some/directory');
});

Копирование файлов и папок

The copy method may be used to copy files and directories to new locations. All operations are relative to the project's root directory:

Для копирования файлов и папок существует метод copy. Все операции копирования производятся относительно корневой папки вашего проекта.

elixir(function(mix) {
    mix.copy('vendor/foo/bar.css', 'public/css/bar.css');
});

elixir(function(mix) {
    mix.copy('vendor/package/views', 'resources/views');
});

Версионирование / Очистка кеша

Многие разработчики добавляют суффикс с меткой времени или уникальным токеном к названиям скомпилированных медиа файлов (assets) чтобы заставить браузер загружать не закешированные файлы, а новые при каждой загрузке страницы. Для данной функции Elixir предоставляет вам метод version.

Метод version может принимает названия файлов относительно папки public, и добавляет уникальный хэш к названию файла. К примеру для скомпилированного файла название будет таким: all-16d570a7.css:

elixir(function(mix) {
    mix.version('css/all.css');
});

После создания файла с версией, для корректного подключения этого файла, вы можете использовать глобальный PHP хелпер elixir внутри ваших views. Хелпер elixir автоматически определить хешированное название файла:

<link rel="stylesheet" href="{{ elixir('css/all.css') }}">

Версионирование нескольких файлов

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

elixir(function(mix) {
    mix.version(['css/all.css', 'js/app.js']);
});

После того как файлы с версиями будут скомпилированы, вы можете использовать хелпер elixir для генерации правильных ссылок хешированных файлов. Помните, вам нужно всего лишь добавить оригинальное название файла в хелпере elixir. Хелпер будет использовать оригинальное имя файла для поиска правильной версии хешированного файла:

<link rel="stylesheet" href="{{ elixir('css/all.css') }}">

<script src="{{ elixir('js/app.js') }}"></script>

BrowserSync

BrowserSync автоматически обновит ваш браузер после того как вы что либо измените в ваших медиа файлах (assets). Для того чтобы настроить запуск сервера BrowserSync по команде gulp watch, воспользуйтесь методом browserSync для Elixir:

elixir(function(mix) {
    mix.browserSync();
});

Чтобы включить синхронизацию с браузером, после запуска gulp watch откройте ваше приложение используйте порт 3000: http://homestead.app:3000. Если вместо homestead.app у вас подключен собственный домен, тогда вы можете указать массив настроек в качестве первого аргумента метода browserSync:

elixir(function(mix) {
    mix.browserSync({
        proxy: 'project.app'
    });
});

Вызов существующих задач gulp

Если вам нужно вызвать существующую Gulp задачу с помощью Elixir, вы можете воспользоваться методом task. В качестве примера представьте что у вас уже есть Gulp задача, которая просто печатает текст при вызове:

gulp.task('speak', function() {
    var message = 'Tea...Earl Grey...Hot';

    gulp.src('').pipe(shell('say ' + message));
});

Если вы хотите вызвать эту задачу с помощью Elixir, тогда метод mix.task указав только имя вашей задачи в качестве аргумента метода:

elixir(function(mix) {
    mix.task('speak');
});

Собственные наблюдатели (watchers)

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

elixir(function(mix) {
    mix.task('speak', 'app/**/*.php');
});

Пишем расширения Elixir

Если вам нужно еще больше гибкости, то метод Elixir'а task поможет вам создать собственные расширения для Elixir. Расширения Elixir'a позволяют вам указать аргументы ваших сторонниз задач. Например, вы можете написать такое расширение:

// File: elixir-extensions.js

var gulp = require('gulp');
var shell = require('gulp-shell');
var Elixir = require('laravel-elixir');

var Task = Elixir.Task;

Elixir.extend('speak', function(message) {

    new Task('speak', function() {
        return gulp.src('').pipe(shell('say ' + message));
    });

});

// mix.speak('Hello World');

И это всё! Обратите внимание что специальную логику Gulp, следует разместить в функции-замыкании, которая указана в качестве второго параметра в конструкторе Task. Вы можете разместить её в начале вашего Gulp файла, или извлечь в отдельный файл задачи. Например, если вы разместите ваши расширения в файле elixir-extensions.js, вы можете потребовать (require) файл из вашего основного файла Gulpfile:

// File: Gulpfile.js

var elixir = require('laravel-elixir');

require('./elixir-extensions')

elixir(function(mix) {
    mix.speak('Tea, Earl Grey, Hot');
});

Собственные наблюдатели (watchers)

Если вы хотите вызывать вашу собственную задачу тогда когда запущена команда gulp watch, вы можете зарегестрировать наблюдатель так:

new Task('speak', function() {
    return gulp.src('').pipe(shell('say ' + message));
})
.watch('./app/**');