1、簡介
LaravelElixir提供了一套乾淨、平滑的 API 用於為 Laravel 應用定義基本的 Gulp任務。Elixir 支援一些通用的 CSS和 JavaScript前置處理器,甚至測試載入器。使用方法鏈,Elixir 允許你平滑的定義資源管道。例如:
elixir(function(mix) { mix.sass('app.scss') .coffee('app.coffee');});
如果你曾經對如何使用Gulp 和 編譯前端資源感到困惑,那麼你會愛上 Laravel Elixir。然而,並不是強制要求在開發期間使用它。你可以自由選擇使用任何前端資源管道工具,或者壓根不使用。
2、安裝 & 設定
2.1 安裝 Node
在開始 Elixir 之前,必須首先確保Node.js 在機器上已經安裝:
node -v
預設情況下,Laravel Homestead 包含你需要的一切;然而,如果你不使用 Vagrant,你也可以通過訪問 Node的下載頁面輕鬆的安裝 Node。
2.2 Gulp
接下來,需要安裝 Gulp 作為全域 NPM 包:
npm install --global gulp
2.3 Laravel Elixir
最後,在新安裝的 Laravel 根目錄下,你會發現有一個 package.json檔案。該檔案和 composer.json一樣,只不過是用來定義 Node 依賴而非 PHP,你可以通過運行如下命令來安裝需要的依賴:
npm install
如果你正在 Windows 系統上開發,需要在運行 npm install命令時帶上 --no-bin-links:
npm install --no-bin-links
3、運行Elixir
Elixir 基於 Gulp,所以要運行 Elixir 命令你只需要在終端中運行 gulp命令即可。添加 --production標識到命令將會最小化 CSS 和 JavaScript 檔案:
// Run all tasks...gulp// Run all tasks and minify all CSS and JavaScript...gulp --production
監控前端資源改變
由於每次修改前端資源後都要運行 gulp很不方便,可以使用 gulp watch命令。該命令將會一直在終端運行並監控前端檔案的改動。當改變發生時,新檔案將會自動被編譯:
gulp watch
4、處理CSS
項目根目錄下的 gulpfile.js檔案包含了所有的 Elixir 任務。Elixir 任務可以使用方法鏈的方式連結起來用於定義前端資源如何被編譯。
4.1 Less
要將 Less編譯成 CSS,可以使用 less方法。 less方法假定你的 Less 檔案都放在 resources/assets/less。預設情況下,本例中該任務會將編譯後的 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' ]);});
如果你想要自訂編譯後檔案的輸出位置,可以傳遞第二個參數到 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');});
4.2 Sass
sass方法允許你將 Sass編譯成 CSS。假定你的 Sass 檔案存放在 resources/assets/sass,你可以像這樣使用該方法:
elixir(function(mix) { mix.sass('app.scss');});
同樣,和 less方法一樣,你可以將多個指令碼編譯成單個 CSS 檔案,甚至自訂結果 CSS 的輸出路徑:
elixir(function(mix) { mix.sass([ 'app.scss', 'controllers.scss' ], 'public/assets/css');});
4.3 原生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');});
4.4 源地圖
預設源地圖被啟用,所以,對於每一個你編譯過的檔案都可以在同一目錄下找到一個對應的 *.css.map檔案。這種匹配允許你在瀏覽器中調試時將編譯過的樣式選取器回溯到原來的 Sass 或 Less。
如果你不想為 CSS 產生源地圖,可以使用一個簡單配置選項關閉它們:
elixir.config.sourcemaps = false;elixir(function(mix) { mix.sass('app.scss');});
5、處理JavaScript
Elixir 還提供了多個函數協助你處理 JavaScript 檔案,例如編譯 ECMAScript 6,CoffeeScript,Browserify,最小化以及簡單串連原生JavaScript檔案。
5.1 CoffeeScript
coffee方法用於將 CoffeeScript編譯成原生 JavaScript。該方法接收關聯到 resources/assets/coffee目錄的 CoffeeScript 檔案的一個字串或數組並在 public/js目錄下產生單個 app.js檔案:
elixir(function(mix) { mix.coffee(['app.coffee', 'controllers.coffee']);});
5.2 Browserify
Elixir 還提供了 browserify方法,從而讓你可以在瀏覽器中引入模組並使用 EcmaScript 6。
該任務假定你的指令碼都存放在 resources/assets/js而且將結果檔案存放到 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');});
5.3 Babel
babel方法可用於將 EcmaScript 6和7編譯成原生JavaScript。該方法接收相對於 resources/assets/js目錄的檔案數組,並在 public/js目錄下產生單個 all.js:
elixir(function(mix) { mix.babel([ 'order.js', 'product.js' ]);});
要選擇不同的輸出路徑,只需將目標路徑作為第二個參數傳遞給該方法。處了 Babel 編譯之外, babel和 mix.scripts()的使用方法和功能差不多。
5.4 指令碼
如果你有多個 JavaScript 檔案想要編譯成單個檔案,可以使用 scripts方法。
scripts方法假定所有路徑相對於 resources/assets/js目錄,而且所有結果 JavaScript 預設存放在 public/js/all.js:
elixir(function(mix) { mix.scripts([ 'jquery.js', 'app.js' ]);});
如果你需要將多個指令碼集合合并到不同的檔案,需要多次調用 scripts方法。該方法的第二個參數決定每個合并的結果檔案名:
elixir(function(mix) { mix.scripts(['app.js', 'controllers.js'], 'public/js/app.js') .scripts(['forum.js', 'threads.js'], 'public/js/forum.js');});
如果你需要將多個指令碼合并到給定目錄,可以使用 scriptsIn方法。結果 JavaScript 會被存放到 public/js/all.js:
elixir(function(mix) { mix.scriptsIn('public/js/some/directory');});
6、拷貝檔案/目錄
你可以使用 copy方法拷貝檔案/目錄到新路徑,所有操作都相對於項目根目錄:
elixir(function(mix) { mix.copy('vendor/foo/bar.css', 'public/css/bar.css');});elixir(function(mix) { mix.copy('vendor/package/views', 'resources/views');});
7、版本號碼/緩衝重新整理
很多開發人員會給編譯的前端資源新增時間戳記或者唯一令牌尾碼以強制瀏覽器載入最新版本而不是代碼的快取複本。Elixir 可以使用 version方法為你處理這種情況。
version方法接收相對於 public目錄的檔案名稱,附加唯一hash到檔案名稱,從而實現緩衝重新整理。例如,產生的檔案名稱看上去是這樣—— all-16d570a7.css:
elixir(function(mix) { mix.version('css/all.css');});
產生版本檔案後,可以在視圖中使用 Elixir 全域的 PHP 協助函數 elixir方法來載入相應的帶hash值的前端資源, elixir函數會自動判斷hash檔案名稱:
給多個檔案加上版本號碼
你可以傳遞一個數組到 version方法來為多個檔案添加版本號碼:
elixir(function(mix) { mix.version(['css/all.css', 'js/app.js']);});
一旦檔案被加上版本號碼,就可以使用協助函數 elixir來產生指向該hash檔案的連結。記住,你只需要傳遞沒有hash值的檔案名稱到 elixir方法。該協助函數使用未加hash值的檔案名稱來判斷檔案當前的hash版本:
8、BrowserSync
BrowserSync 會在你修改前端資源後自動重新整理瀏覽器,運行 gulp watch命令時你可以使用 browserSync方法告知Elixir 啟動一個 BrowserSync 伺服器:
elixir(function(mix) { mix.browserSync();});
運行 gulp watch後,使用 http://homestead.app:3000訪問應用來開啟瀏覽器同步。如果你在本地開發中使用 homestead.app之外的其它網域名稱,可以傳遞網域名稱參數到 browserSync方法:
elixir(function(mix) { mix.browserSync({ proxy: 'project.app' });});
9、調用存在的Gulp任務
如果你需要從 Elixir 調用已存在的 Gulp 任務,可以使用 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');});
自訂監控者
如果你需要註冊一個監控器在每一次檔案修改時都運行自訂任務,傳遞一個Regex作為 task方法的第二個參數:
elixir(function(mix) { mix.task('speak', 'app/**/*.php');});
10、編寫 Elixir擴充
如果你需要比 Elixir 的 task方法所提供的更加靈活的功能,可以建立自訂的 Elixir 擴充。Elixir 擴充允許你傳遞參數到自訂任務,例如,你可以像這樣編寫一個擴充:
// File: elixir-extensions.jsvar 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構造器。你可以將其放在 Gulpfile頂端,或者將其解析到自訂的任務檔案。例如,如果你將擴充放在 elixir-extensions.js,可以在主 Gulpfile中像這樣引入該檔案:
// File: Gulpfile.jsvar elixir = require('laravel-elixir');require('./elixir-extensions')elixir(function(mix) { mix.speak('Tea, Earl Grey, Hot');});
自訂監控器
如果你想要自訂任務在運行 gulp watch的時候被觸發,可以註冊一個監控器:
new Task('speak', function() { return gulp.src('').pipe(shell('say ' + message));}).watch('./app/**');