Laravel Elixir
提供了一套干凈、平滑的 API
用于為 Laravel
應(yīng)用定義基本的Gulp任務(wù)。Elixir 支持一些通用的
CSS 和
JavaScript 預(yù)處理器,甚至是測試工具。使用方法鏈,
Elixir `允許你平滑的定義資源管道。例如:
elixir(function(mix) {
mix.sass('app.scss')
.coffee('app.coffee');
});
如果你曾經(jīng)對如何開始 Gulp
和前端資源編譯感到困惑,那么你會愛上 Laravel Elixir
。然而,并不是強制要求在開發(fā)期間使用它。你可以自由選擇使用任何前端資源管道工具,或者壓根不使用。
在開始 Elixir
之前,必須首先確保 Node.js
在機器上已經(jīng)安裝:
node -v
默認(rèn)情況下, Laravel Homestead
包含你需要的一切;然而,如果你不使用 Vagrant
,你也可以通過訪問 Node
的下載頁面輕松的安裝 Node。
接下來,需要安裝 Gulp
作為全局 NPM
包:
npm install --global gulp
最后,在新安裝的 Laravel
根目錄下,你會發(fā)現(xiàn)有一個 package.json
文件。該文件和 composer.json
一樣,只不過是用來定義 Node
依賴而非 PHP
,你可以通過運行如下命令來安裝需要的依賴:
npm install
如果你正在 Windows
系統(tǒng)上開發(fā),需要在運行 npm install
命令時帶上--no-bin-links
:
npm install --no-bin-links
Elixir
基于 Gulp
,所以要運行 Elixir
命令你只需要在終端中運行 gulp
命令即可。添加--production
標(biāo)識到命令將會最小化 CSS
和 JavaScript
文件:
// Run all tasks...
gulp
// Run all tasks and minify all CSS and JavaScript...
gulp --production
由于每次修改前端資源后都要運行 gulp
很不方便,可以使用 gulp watch
命令。該命令將會一直在終端運行并監(jiān)控前端文件的改動。當(dāng)改變發(fā)生時,新文件將會自動被編譯:
gulp watch
項目根目錄下的 gulpfile.js
文件包含了所有的 Elixir
任務(wù)。Elixir
任務(wù)可以使用方法鏈的方式鏈接起來用于定義前端資源如何被編譯。
要將 Less
編譯成 CSS
,可以使用 less
方法。less
方法假定你的 Less
文件都放在 resources/assets/less
。默認(rèn)情況下,本例中該任務(wù)會將編譯后的 CSS
放到 public/css/app.css
:
elixir(function(mix) {
mix.less('app.less');
});
你還可以將多個 Less
文件編譯成單個 CSS
文件。同樣,該文件會被放到 public/css/app.css
:
elixir(function(mix) {
mix.less([
'app.less',
'controllers.less'
]);
});
如果你想要自定義編譯后文件的輸出位置,可以傳遞第二個參數(shù)到 less
方法:
elixir(function(mix) {
mix.less('app.less', 'public/stylesheets');
});
// Specifying a specific output filename...
elixir(function(mix) {
mix.less('app.less', 'public/stylesheets/style.css');
});
sass
方法允許你將 Sass
編譯成 CSS
。假定你的 Sass
文件存放在 resources/assets/sass
,你可以像這樣使用該方法:
elixir(function(mix) {
mix.sass('app.scss');
});
同樣,和 less
方法一樣,你可以將多個腳本編譯成單個 CSS
文件,甚至自定義結(jié)果 CSS
的輸出路徑:
elixir(function(mix) {
mix.sass([
'app.scss',
'controllers.scss'
], 'public/assets/css');
});
如果你只想要將多個原生 CSS
樣式文件合并到一個文件,可以使用 styles
方法。傳遞給該方法的路徑相對于 resources/assets/css
目錄,結(jié)果 CSS
被存放在 public/css/all.css
:
elixir(function(mix) {
mix.styles([
'normalize.css',
'main.css'
]);
});
當(dāng)然,你還可以通過傳遞第二個參數(shù)到 styles
方法來輸出結(jié)果文件到一個自定義路徑:
elixir(function(mix) {
mix.styles([
'normalize.css',
'main.css'
], 'public/assets/css');});
默認(rèn)源地圖被啟用,所以,對于每一個你編譯過的文件都可以在同一目錄下找到一個對應(yīng)的*.css.map 文件。這種匹配允許你在瀏覽器中調(diào)試時將編譯過的樣式選擇器回溯到原來的 Sass
或 Less
。
如果你不想為 CSS
生成源地圖,可以使用一個簡單配置選項關(guān)閉它們:
elixir.config.sourcemaps = false;
elixir(function(mix) {
mix.sass('app.scss');
});
Elixir
還提供了多個函數(shù)幫助你處理 JavaScript
文件,例如編譯 ECMAScript 6
,CoffeeScript
,Browserify
,最小化以及簡單連接原生 JavaScript
文件。
coffee
方法用于將 CoffeeScript
編譯成原生 JavaScript
。該方法接收關(guān)聯(lián)到 resources/assets/coffee
目錄的 CoffeeScript
文件的一個字符串或數(shù)組并在 public/js
目錄下生成單個 app.js
文件:
elixir(function(mix) {
mix.coffee(['app.coffee', 'controllers.coffee']);
});
Elixir
還提供了 browserify
方法,從而讓你可以在瀏覽器中引入模塊并使用 EcmaScript 6
。
該任務(wù)假定你的腳本都存放在 resources/assets/js
而且將結(jié)果文件存放到 public/js/bundle.js
:
elixir(function(mix) {
mix.browserify('main.js');
});
除了處理 Partialify
和 Babelify
,還可以安裝并添加更多:
npm install vueify --save-dev
elixir.config.js.browserify.transformers.push({
name: 'vueify',
options: {}
});
elixir(function(mix) {
mix.browserify('main.js');
});
babel
方法可用于將EcmaScript 6
和 7
編譯成原生 JavaScript
。該方法接收相對于 resources/assets/js
目錄的文件數(shù)組,并在 public/js
目錄下生成單個 all.js
:
elixir(function(mix) {
mix.babel([
'order.js',
'product.js'
]);});
要選擇不同的輸出路徑,只需將目標(biāo)路徑作為第二個參數(shù)傳遞給該方法。處了 Babel
編譯之外,babel
和 mix.scripts()
的使用方法和功能差不多。
如果你有多個 JavaScript
文件想要編譯成單個文件,可以使用 scripts 方法。
scripts 方法假定所有路徑相對于 resources/assets/js
目錄,而且所有結(jié)果 JavaScript
默認(rèn)存放在 public/js/all.js
:
elixir(function(mix) {
mix.scripts([
'jquery.js',
'app.js'
]);
});
如果你需要將多個腳本集合合并到不同的文件,需要多次調(diào)用 scripts
方法。該方法的第二個參數(shù)決定每個合并的結(jié)果文件名:
elixir(function(mix) {
mix.scripts(['app.js', 'controllers.js'], 'public/js/app.js')
.scripts(['forum.js', 'threads.js'], 'public/js/forum.js');
});
如果你需要將多個腳本合并到給定目錄,可以使用 scriptsIn
方法。結(jié)果 JavaScript
會被存放到 public/js/all.js
:
elixir(function(mix) {
mix.scriptsIn('public/js/some/directory');
});
很多開發(fā)者會給編譯的前端資源添加時間戳或者唯一令牌后綴以強制瀏覽器加載最新版本而不是代碼的緩存副本。Elixir
可以使用 version
方法為你處理這種情況。
version
方法接收相對于 public
目錄的文件名,附加唯一 hash
到文件名,從而實現(xiàn)緩存刷新。例如,生成的文件名看上去是這樣——all-16d570a7.css:
elixir(function(mix) {
mix.version('css/all.css');
});
生成版本文件后,可以在視圖中使用 Elixir
全局的 PHP
幫助函數(shù) elixir
方法來加載相應(yīng)的帶 hash
值的前端資源,elixir
函數(shù)會自動判斷 hash
文件名:
<link rel="stylesheet" href="{{ elixir('css/all.css') }}">
你可以傳遞一個數(shù)組到 version
方法來為多個文件添加版本號:
elixir(function(mix) {
mix.version(['css/all.css', 'js/app.js']);
});
一旦文件被加上版本號,就可以使用幫助函數(shù) elixir
來生成指向該 hash
文件的鏈接。記住,你只需要傳遞沒有 hash
值的文件名到 elixir
方法。該幫助函數(shù)使用未加 hash
值的文件名來判斷文件當(dāng)前的 hash
版本:
<link rel="stylesheet" href="{{ elixir('css/all.css') }}">
<script src="{{ elixir('js/app.js') }}"></script>
如果你需要從 Elixir
調(diào)用已存在的 Gulp
任務(wù),可以使用 task
方法。例如,假定你有一個調(diào)用時只是簡單說幾句話的 Gulp
任務(wù):
gulp.task('speak', function() {
var message = 'Tea...Earl Grey...Hot';
gulp.src('').pipe(shell('say ' + message));
});
如果你想要從 Elixir
中調(diào)用該任務(wù),使用 mix.task
方法并傳遞任務(wù)名作為該方法的唯一參數(shù):
elixir(function(mix) {
mix.task('speak');
});
如果你需要注冊一個監(jiān)控器在每一次文件修改時都運行自定義任務(wù),傳遞一個正則表達式作為 task
方法的第二個參數(shù):
elixir(function(mix) {
mix.task('speak', 'app/**/*.php');});
如果你需要比 Elixir
的 task
方法所提供的更加靈活的功能,可以創(chuàng)建自定義的 Elixir
擴展。Elixir
擴展允許你傳遞參數(shù)到自定義任務(wù),例如,你可以像這樣編寫一個擴展:
// 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
邏輯應(yīng)該放到閉包函數(shù)里作為第二個參數(shù)傳遞給 Task
構(gòu)造器。你可以將其放在 Gulpfile
頂端,或者將其解析到自定義的任務(wù)文件。例如,如果你將擴展放在 elixir-extensions.js
,可以在主 Gulpfile
中像這樣引入該文件:
// File: Gulpfile.js
var elixir = require('laravel-elixir');
require('./elixir-extensions')
elixir(function(mix) {
mix.speak('Tea, Earl Grey, Hot');
});
如果你想要自定義任務(wù)在運行 gulp watch
的時候被觸發(fā),可以注冊一個監(jiān)控器:
new Task('speak', function() {
return gulp.src('').pipe(shell('say ' + message));
}).watch('./app/**');