{{TOC}} {{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11}} == Введение == Laravel Elixir предоставляет чистый и гибкий API для определения основных ((http://gulpjs.com Gulp))-задач вашего Laravel-приложения. Elixir поддерживает основные препроцессоры CSS и JavaScript, такие как ((http://sass-lang.com Sass)) и ((https://webpack.github.io/ Webpack)). С помощью сцепки методов Elixir позволяет вам гибко определять свой файлопровод (asset pipeline). Например: %%(JS) elixir(function(mix) { mix.sass('app.scss') .webpack('app.js'); }); %% Если вы сомневались и путались, с чего начать работу с Gulp и компиляцией ресурсов, то вам точно понравится Laravel Elixir. Но вам необязательно использовать именно его при разработке своего приложения. Вы можете использовать любой другой инструмент для файлопровода, или вообще не использовать его. == Установка и настройка == **Установка Node** Перед запуском Elixir необходимо убедиться, что на вашем компьютере установлен Node.js и NPM (для версии 5.3 и выше). %%(sh) node -v npm -v %% По умолчанию Laravel Homestead включает в себя всё необходимое. Однако, если вы не используете Vagrant, то вы можете легко установить свежие версии Node и NPM с помощью простых графических установщиков с их ((http://nodejs.org/en/download/ страницы загрузки)). **Gulp** После вам надо получить ((http://gulpjs.com Gulp)) как глобальный NPM-пакет: %%(sh) npm install --global gulp %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15) %%(sh) npm install --global gulp-cli ~%% Если вы используете систему контроля версий, то можете выполнить команду %%(sh)npm shrinkwrap%%, чтобы зафиксировать свои NPM-требования: %%(sh) npm shrinkwrap ~%% После выполнения этой команды, вы можете "закоммитить" ((https://docs.npmjs.com/cli/shrinkwrap npm-shrinkwrap.json)) в контроль версий. %% **Laravel Elixir** Осталось только установить Laravel Elixir. В корневом каталоге установленного Laravel вы найдете файл %%(t)package.json%%. Стандартный файл %%(t)package.json%% содержит JavaScript-модули Elixir и Webpack. Это то же самое, что и файл %%(t)composer.json%%, только он определяет зависимости Node, а не PHP. Вы можете установить перечисленные в нём зависимости выполнив: %%(sh) npm install %% Если вы разрабатываете в системе Windows или запускаете виртуальную машину с Windows, вам может потребоваться команда %%(sh)npm install%% с ключом %%(sh)--no-bin-links%%: %%(sh) npm install --no-bin-links %% == Запуск Elixir == Elixir построен на основе ((http://gulpjs.com/ Gulp)), поэтому для запуска задач Elixir вам надо просто выполнить консольную команду %%(sh)gulp%%. А ключ %%(sh)--production%% минимизирует ваши файлы CSS и JavaScript: %%(sh) // Запустить все задачи... gulp // Запустить все задачи и минимизировать все файлы CSS и JavaScript... gulp --production %% При выполнении этой команды вы увидите красиво оформленную таблицу с информацией о всех выполненных при этом операциях. **Отслеживание изменений ресурсов** Команда %%(sh)gulp watch%% после запуска продолжает выполняться в терминале и следит за всеми изменениями ваших ресурсов. Gulp автоматически перекомпилирует ваши ресурсы, если вы измените их, пока запущена команда %%(sh)watch%%: %%(sh) gulp watch %% == Работа с таблицами стилей == Файл %%(t)gulpfile.js%% в корневом каталоге вашего проекта содержит все ваши Elixir-задачи. Elixir-задачи могут быть сцеплены вместе для точного определения того, как должны быть скомпилированы ваши ресурсы. === Компилирование Less === Чтобы скомпилировать ((http://lesscss.org/ Less)) в CSS используется метод %%less()%%. Этот метод предполагает, что ваши файлы находятся в %%(t)resources/assets/less%%. В этом примере задача по умолчанию поместит скомпилированную CSS в %%(t)public/css/app.css%%: %%(JS) elixir(function(mix) { mix.less('app.less'); }); %% Также вы можете комбинировать несколько Less-файлов в один CSS-файл. Итоговая CSS будет помещена в %%(t)public/css/app.css%%: %%(JS) elixir(function(mix) { mix.less([ 'app.less', 'controllers.less' ]); }); %% Указать другой путь для сохранения итоговых файлов можно вторым аргументом метода %%less()%%: %%(JS) elixir(function(mix) { mix.less('app.less', 'public/stylesheets'); }); // Указание конкретного имени выходного файла... elixir(function(mix) { mix.less('app.less', 'public/stylesheets/style.css'); }); %% === Компилирование Sass === Метод %%sass()%% позволяет компилировать ((http://sass-lang.com/ Sass)) в CSS. Предполагается, что ваши Sass-файлы хранятся в %%(t)resources/assets/sass%%. %%(JS) elixir(function(mix) { mix.sass('app.scss'); }); %% %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) По умолчанию Elixir под капотом использует библиотеку LibSass для компиляции. В некоторых случаях это может оказаться выгодней, чем использование версии Ruby, которая работает медленнее, но зато более функциональна. Если у вас установлены и Ruby и Sass (%%(sh)gem install sass%%), вы можете включить Ruby-режим: %%(JS) elixir(function(mix) { mix.rubySass("app.sass"); }); ~%% %% %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=f60f8b3697b3ffe381df4ddb7e2875ffce940643 1.04.2016 17:39:10) Как и в случае с методом %%less()%%, вы можете компилировать несколько Sass-файлов в один CSS-файл, и задать папку для сохранения итоговой CSS: %%(JS) elixir(function(mix) { mix.sass([ 'app.scss', 'controllers.scss' ], 'public/assets/css'); }); ~%% %% %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51) **Изменение путей** Рекомендуется использовать стандартные каталоги Laravel для ресурсов, но если вам необходима другой базовый каталог, вы можете указать путь к любому файлу начиная с %%(t)./%%. Тогда Elixir поймёт, что надо начать с корня проекта, а не использовать стандартный базовый каталог. Например, чтобы скомпилировать файл из %%(t)app/assets/sass/app.scss%% и разместить результат в %%(t)public/css/app.css%%, вам надо сделать такой вызов метода %%sass()%%: %%(JS) elixir(function(mix) { mix.sass('./app/assets/sass/app.scss'); }); ~%% === Компилирование Stylus === Для компилирования ((http://stylus-lang.com/ Stylus)) в CSS используется метод %%stylus()%%. Если ваши Stylus-файлы хранятся в %%(t)resources/assets/stylus%%, вызовите метод вот так: %%(JS) elixir(function(mix) { mix.stylus('app.styl'); }); ~%% .(alert) Эта сигнатура метода идентична и для %%mix.less()%% и для %%mix.sass()%%. %% %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=f60f8b3697b3ffe381df4ddb7e2875ffce940643 1.04.2016 17:39:10) === Компилирование простых CSS === Если вы хотите просто скомбинировать некоторые простые таблицы стилей в один файл, используйте метод %%styles()%%. Передаваемые в этот метод пути относительны к %%(t)resources/assets/css%%, а итоговая CSS будет помещена в %%(t)public/css/all.css%%: %%(JS) elixir(function(mix) { mix.styles([ 'normalize.css', 'main.css' ]); }); ~%% Вы также можете указать Elixir сохранить итоговый файл в другой каталог или файл, передав второй аргумент в метод %%styles()%%: %%(JS) elixir(function(mix) { mix.styles([ 'normalize.css', 'main.css' ], 'public/assets/css/site.css'); }); ~%% %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=f60f8b3697b3ffe381df4ddb7e2875ffce940643 1.04.2016 17:39:10) **Комбинирование стилей и сохранение по базовому пути** %%(JS) elixir(function(mix) { mix.styles([ "normalize.css", "main.css" ], 'public/build/css/everything.css', 'public/css'); }); ~%% Третий аргумент методов %%styles()%% и %%scripts()%% определяет относительный каталог для всех путей, передаваемых в методы. **Комбинирование всех стилей в каталоге** %%(JS) elixir(function(mix) { mix.stylesIn("public/css"); }); ~%% %% === Компилирование без карт кода === В Elixir карты кода (source maps) включены по умолчанию и обеспечивают более полную отладочную информацию для инструментов разработчика в вашем браузере при использовании скомпилированных ресурсов. Для каждого скомпилированного файла вы найдете соответствующий ему файл %%(t)*.css.map%% или %%(t)*.js.map%% в том же каталоге. Чтобы отключить эту функцию, просто отключите настройку %%(t)sourcemaps%%: %%(JS) elixir.config.sourcemaps = false; elixir(function(mix) { mix.sass('app.scss'); }); %% == Работа со скриптами == Elixir предоставляет несколько функций для работы с JavaScript-файлами, например: компилирование ECMAScript 2015, сбор модулей, ((ВП:минификация)) и простая конкатенация простых JavaScript-файлов. %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51) При написании ES2015 с модулями у вас есть выбор между ((https://webpack.github.ioWebpack)) и ((http://rollupjs.org/ Rollup)). Если эти инструменты вам незнакомы, не беспокойтесь, Elixir сам выполнит всю сложную работу. По умолчанию %%(t)gulpfile%% Laravel использует %%(t)webpack%% для компилирования Javascript, но вы можете использовать любой другой сборщик модулей. === Компилирование Webpack === Для компилирования и сборки ((https://babeljs.io/docs/learn-es2015/ ECMAScript 2015)) в простой JavaScript служит метод %%webpack()%%. Эта функция принимает путь к файлу относительно каталога %%(t)resources/assets/js%% и генерирует один собранный файл в каталоге %%(t)public/js%%: %%(JS) elixir(function(mix) { mix.webpack('app.js'); }); ~%% Для выбора другого каталога для вывода или базового каталога просто укажите необходимые пути с точкой в начале. Затем вы можете указать пути относительно корня вашего приложения. Например, чтобы скомпилировать %%(t)app/assets/js/app.js%% в %%(t)public/dist/app.js%%: %%(JS) elixir(function(mix) { mix.webpack( './app/assets/js/app.js', './public/dist' ); }); ~%% Если вы хотите использовать функциональность Webpack по полной, Elixir прочитает любой файл %%(t)webpack.config.js%%, находящийся в корне вашего проекта, и ((https://webpack.github.io/docs/configuration.html включит его настройки)) в процесс сборки. === Компилирование Rollup === Подобно Webpack, Rollup - это сборщик для ES2015 следующего поколения. Эта функция принимает массив файлов относительно каталога %%(t)resources/assets/js%% и генерирует один файл в каталоге %%(t)public/js%%: %%(JS) elixir(function(mix) { mix.rollup('app.js'); }); ~%% Как и с методом %%webpack()%% вы можете настроить место для ввода и вывода файлов, передаваемых в метод %%rollup()%%: ~%% elixir(function(mix) { mix.rollup( './resources/assets/js/app.js', './public/dist' ); }); ~%% %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) === Компилирование CoffeeScript === Для компилирования ((http://coffeescript.org/ CoffeeScript)) в простой JavaScript служит метод %%coffee()%%. Он принимает строку или массив CoffeeScript-файлов относительно пути %%(t)resources/assets/coffee%% и генерирует единый файл %%(t)public/js/app.js%%: %%(JS) elixir(function(mix) { mix.coffee(['app.coffee', 'controllers.coffee']); }); ~%% %% %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) **Компилирование всех Less and CoffeeScript** %%(JS) elixir(function(mix) { mix.less() .coffee(); }); ~%% **Выполнение тестов PHPUnit** %%(JS) elixir(function(mix) { mix.phpUnit(); }); ~%% **Выполнение тестов PHPSpec** %%(JS) elixir(function(mix) { mix.phpSpec(); }); ~%% %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) === Browserify === В Elixir есть метод %%browserify ()%%, который обеспечивает вас всеми преимуществами запроса модулей в браузере и ECMAScript 6 и JSX (для версии 5.2 и выше). Эта задача предполагает, что ваши скрипты хранятся в %%(t)resources/assets/js%%, и сохранит итоговый файл в %%(t)public/js/main.js%%: %%(JS) elixir(function(mix) { mix.browserify('main.js'); }); ~%% %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15) При необходимости вы можете передать другое место для вывода в качестве второго аргумента %%(JS) // Задание конкретного имени для вывода файла... elixir(function(mix) { mix.browserify('main.js', 'public/javascripts/main.js'); }); ~%% %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) В ((http://browserify.org/ Browserify)) уже включены трансформеры Partialify и Babelify, при необходимости вы можете установить и добавить другие: %%(sh) npm install aliasify --save-dev ~%% %%(JS) elixir.config.js.browserify.transformers.push({ name: 'aliasify', options: {} }); elixir(function(mix) { mix.browserify('main.js'); }); ~%% === Babel === Для компилирования ((https://babeljs.io/docs/learn-es2015/ ECMAScript 6 и 7)) и ((https://facebook.github.io/react/docs/jsx-in-depth.html JSX)) (для версии 5.2 и выше) в простой JavaScript служит метод %%babel()%%. Он принимает массив или файлы относительно пути %%(t)resources/assets/js%%, и генерирует единый файл %%(t)public/js/all.js%%: %%(JS) elixir(function(mix) { mix.babel([ 'order.js', 'product.js', 'react-component.jsx' //для версии 5.2 и выше ]); }); ~%% Другое место для сохранения итогового файла можно указать вторым аргументом. Сигнатура и функциональность этого метода идентичны %%mix.scripts()%%, за исключением компилирования Babel. %% === Скрипты === Чтобы скомбинировать несколько JavaScript-файлов в один, используйте метод %%scripts()%%, который обеспечивает автоматические карты кода, конкатенацию и ((ВП:минификация минификацию)). Метод %%scripts()%% работает с файлами по относительному пути %%(t)resources/assets/js%% и сохраняет итоговый JavaScript в %%(t)public/js/all.js%%: %%(JS) elixir(function(mix) { mix.scripts([ 'order.js', 'forum.js' ]); }); %% Если вам необходимо конкатенировать несколько наборов скриптов в разные файлы, вы можете сделать несколько вызовов метода %%scripts()%%. Имя итогового файла для каждой конкатенации определяется вторым аргументом метода: %%(JS) elixir(function(mix) { mix.scripts(['app.js', 'controllers.js'], 'public/js/app.js') .scripts(['forum.js', 'threads.js'], 'public/js/forum.js'); }); %% Если вам необходимо скомбинировать все скрипты в данной папке, используйте метод %%scriptsIn()%%. Итоговый JavaScript будет помещён в %%(t)public/js/all.js%%: %%(JS) elixir(function(mix) { mix.scriptsIn('public/js/some/directory'); }); %% .(alert) Если вы собираетесь конкатенировать несколько предварительно минифицированных библиотек от производителей, таких как jQuery, попробуйте вместо этого использовать %%mix.combine()%%. При этом файлы будут скомбинированы без выполнения шагов по созданию карт кода и минификации. В результате значительно уменьшится время компилирования. == Копирование файлов и папок == Метод %%copy()%% используется для копирования файлов и папок в новое место. Все операции относительны корневой папки проекта: %%(JS) elixir(function(mix) { mix.copy('vendor/foo/bar.css', 'public/css/bar.css'); %% == Версии файлов /очистка кэша == Многие разработчики добавляют в имена ресурсов время создания или уникальный токен, чтобы браузер загружал свежие ресурсы вместо обработки устаревшего кода. В Elixir для этого служит метод %%version()%%. Метод %%version()%% принимает имя файла относительно папки %%(t)public%% и добавляет к нему уникальный хеш для возможности очистки кэша. Например, сгенерированное имя файла будет выглядеть приблизительно так - %%(t)all-16d570a7.css%%: %%(JS) elixir(function(mix) { mix.version('css/all.css'); }); %% Сгенерировав версию файла, вы можете использовать глобальную функцию Laravel %%elixir()%% в ваших ((/docs/v5/views представлениях)) для загрузки соответствующих хешированных ресурсов. Функция %%elixir()%% автоматически определит текущее имя хешированного файла: %%(html) %% **Версии для нескольких файлов** Вы также можете передать массив в метод %%version()%%, чтобы присвоить версию нескольким файлам: %%(JS) elixir(function(mix) { mix.version(['css/all.css', 'js/app.js']); }); %% Когда файлам присвоена версия, вы можете использовать функцию %%elixir()%% для генерации ссылок к нужным хешированным файлам. Помните, вам надо просто передать в эту функцию имя нехешированного файла. Она использует это имя для определения текущей хешированной версии файла: %%(html) %% %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=f60f8b3697b3ffe381df4ddb7e2875ffce940643 1.04.2016 17:39:10) == BrowserSync== BrowserSync автоматически производит обновление в браузере при изменениях в ваших ресурсах. Метод %%browserSync()%% принимает JavaScript-объект с атрибутом %%(t)proxy%%, содержащим локальный URL вашего приложения. Теперь, когда вы запустите %%(sh)gulp watch%%, вы сможете обращаться к своему приложению через 3000 порт (%%(t)http://project.dev:3000%%) и наслаждаться браузерной синхронизацией: %%(JS) elixir(function(mix) { mix.browserSync({ proxy: 'project.dev' }); }); ~%% %% %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) == Gulp == Теперь, когда вы указали, какие задачи должен выполнять Elixir, вы должны вызвать Gulp из командной строки. **Выполнение всех зарегистрированных задач разом** %%(sh) gulp ~%% **Отслеживание изменений ресурсов** %%(sh) gulp watch ~%% **Только скомпилированные скрипты** %%(sh) gulp scripts ~%% **Только скомпилированные стили** %%(sh) gulp styles ~%% **Отслеживание изменений тестов и PHP-классов** %%(sh) gulp tdd ~%% .(alert) Запуск всех задач будет происходить для среды разработки, и минимизация выполняться не будет. Для продакшна используйте %%(sh)gulp --production%%. %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) == Вызов существующих Gulp-задач == Для вызова существующей Gulp-задачи используйте метод %%task()%%. Как пример, представьте, что у вас есть Gulp-задача, которая просто выводит небольшой текст при вызове. %%(JS) gulp.task('speak', function() { var message = 'Tea...Earl Grey...Hot'; gulp.src('').pipe(shell('say ' + message)); }); ~%% Если вы хотите вызвать эту задачу из Elixir, используйте метод %%mix.task()%% и передайте имя задачи единственным аргументом метода: %%(JS) elixir(function(mix) { mix.task('speak'); }); ~%% **Свои наблюдатели** Если вам необходимо зарегистрировать наблюдателя, чтобы запускать ваши задачи каждый раз, когда изменяется один или несколько файлов, вы можете передать регулярное выражение в качестве второго аргумента метода %%task()%%: %%(JS) elixir(function(mix) { mix.task('speak', 'app/**/*.php'); }); ~%% == Создание расширений Elixir == Для ещё большей гибкости вы можете создать полноценные расширения Elixir. Расширения Elixir позволяют передавать аргументы в ваши задачи. Например, можно написать такое расширение: %%(JS) // 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()%%. Вы можете либо расположить это в начале вашего %%(t)Gulpfile%%, либо вынести в отдельный файл задач. Например, если вы разместите расширения в %%(t)elixir-extensions.js%%, то можете затребовать этот файл из основного (t)Gulpfile%% вот так: %%(JS) // File: Gulpfile.js var elixir = require('laravel-elixir'); require('./elixir-extensions') elixir(function(mix) { mix.speak('Tea, Earl Grey, Hot'); }); ~%% **Свои наблюдатели** Если вы хотите перезапускать свою задачу во время выполнения %%(sh)gulp watch%%, можете зарегистрировать наблюдателя: %%(JS) new Task('speak', function() { return gulp.src('').pipe(shell('say ' + message)); }) .watch('./app/**'); ~%% %%